欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

structc 开源框架简介

程序员文章站 2022-03-18 15:13:39
了解 "structc https://github.com/wangzhione/structc" structc 是 C 构建基础项目框架. 不是太惊艳, 但绝对是 C 简单项目中一股清流. 它的前身是 simplec 框架. "simplec https://github.com/wangzh ......

了解

structc-https://github.com/wangzhione/structc

    structc 是 C 构建基础项目框架. 不是太惊艳, 但绝对是 C 简单项目中一股清流. 
它的前身是 simplec 框架. 

simplec - https://github.com/wangzhione/simplec

 二者相比. structc 框架更加自然. 力求贴合 C 项目开发的原始状态.  所有写的代码, 心愿就是
向着标准库, 操作系统, 编译器靠拢!
例如下面代码
#ifndef _H_THREAD
#define _H_THREAD

#include <struct.h>
#include <pthread.h>
#include <semaphore.h>

//
// pthread_run - 异步启动线程
// id       : &tid 线程id地址
// frun     : 运行的主体
// arg      : 运行参数
// return   : 返回线程构建结果, 0 is success
//
#define pthread_run(id, frun, arg)                                  \
pthread_run_((id), (node_f)(frun), (void *)(intptr_t)(arg))
inline int pthread_run_(pthread_t * id, node_f frun, void * arg) {
    return pthread_create(id, NULL, (start_f)frun, arg);
}

//
// pthread_end - 等待启动线程结束
// tid      : 线程id
// return   : void
//
inline void pthread_end(pthread_t tid) {
    pthread_join(tid, NULL);
}

//
// pthread_async - 异步启动分离线程
// frun     : 运行的主体
// arg      : 运行参数
// return   : 返回 0 is success
// 
#define pthread_async(frun, arg)                            \
pthread_async_((node_f)(frun), (void *)(intptr_t)(arg))

inline int pthread_async_(node_f frun, void * arg) {
    int ret;
    pthread_t tid;
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    ret = pthread_create(&tid, &attr, (start_f)frun, arg);
    pthread_attr_destroy(&attr);

    return ret;
}

#endif//_H_THREAD
有时候想问为什么喜欢用 C 写这些毫无营养的 东东. 在回答这个问题之前.

引述 golang.org 中一段代码 
// You can edit this code!
// Click here and start typing.
package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}
(: 说 real 的, 在写的溜语言中, 唯独 Go 很好用, 但 * 真丑.)

猜测可能还是, C 有点意思 ~ 

借 - https://y.qq.com/n/yqq/song/002WLDmw0vkHtC.html

曾经多少个夜晚 在敲那些字符 printf("Hello World");

解说

    不妨说说 structc 的构成

 引进部分:   

    1. 内存池选用 jemalloc
    2. 复用 IO 选用 libuv
    3. 线程模型选用 pthtread  

补充部分 : 在 winds 争取实现 linux 一样的内容
       1. errno, strerror 机制
       2. socket 机制
       3. select / epoll 机制
       4. time 机制
       5. atom 机制
       ... ... 

核心部分

    1. mq.h     队列      - https://github.com/wangzhione/structc/blob/master/structc/struct/mq.h
    2. dict.h   字典      - https://github.com/wangzhione/structc/blob/master/structc/struct/dict.h
    3. tstr.h   字符串     - https://github.com/wangzhione/structc/blob/master/structc/struct/tstr.h
    4. list.h   单链表     - https://github.com/wangzhione/structc/blob/master/structc/struct/list.h
    5. rtree.h  红黑树     - https://github.com/wangzhione/structc/blob/master/structc/struct/rtree.h 
    6. array.h  动态数组    - https://github.com/wangzhione/structc/blob/master/structc/struct/array.h

... ... 也许可以说, 数据结构 当前 仍是软件设计的源头吧. 

本文虽然作为 structc 拉粉的软文. 但是感觉其中有些数据结构的设计思路很值得借鉴. 
例如 mq.h 中队列 empty or full 思路
//
// pop empty  <=> tail == -1 ( head == 0 )
// push full  <=> head == tail + 1
//
struct mq {
    int head;           // 头结点
    int tail;           // 尾结点
    int size;           // 队列大小
    void ** queue;      // 队列实体

    atom_t lock;        // 队列原子锁
    volatile bool fee;  // true表示销毁状态
};
dict.h 中关于素数表的引入
//
// primes - 质数表
//
const unsigned primes[][2] = {
    { (1<<6)-1  ,         53 },
    { (1<<7)-1  ,         97 },
    { (1<<8)-1  ,        193 },
    { (1<<9)-1  ,        389 },
    { (1<<10)-1 ,        769 },
    { (1<<11)-1 ,       1543 },
    { (1<<12)-1 ,       3079 },
    { (1<<13)-1 ,       6151 },
    { (1<<14)-1 ,      12289 },
    { (1<<15)-1 ,      24593 },
    { (1<<16)-1 ,      49157 },
    { (1<<17)-1 ,      98317 },
    { (1<<18)-1 ,     196613 },
    { (1<<19)-1 ,     393241 },
    { (1<<20)-1 ,     786433 },
    { (1<<21)-1 ,    1572869 },
    { (1<<22)-1 ,    3145739 },
    { (1<<23)-1 ,    6291469 },
    { (1<<24)-1 ,   12582917 },
    { (1<<25)-1 ,   25165843 },
    { (1<<26)-1 ,   50331653 },
    { (1<<27)-1 ,  100663319 },
    { (1<<28)-1 ,  201326611 },
    { (1<<29)-1 ,  402653189 },
    { (1<<30)-1 ,  805306457 },
    { UINT_MAX  , 1610612741 },
};
说起 (1<<6) - 1 不妨问问大家 (2 ^ 6) - 1 是多少 ? 是不是也很有意思 : )

或者 rtree.h 中 
//
// 红黑树通用结构, 需要将 $RTREE 放在结构开头部位
//

struct $rtree {
    uintptr_t parentc;
    struct $rtree * left;
    struct $rtree * right;
};
等等 ... ... 不一一列举. structc 的代码很有实战参照意义. 

有兴趣的同学可以详细看看, 顺带肉眼帮我提提 BUG, 在此表示感谢 . : )

后继

    错误是难免的, 欢迎指正. 
这里最后开启程序员写代码模式, 跳个函数结尾  
// _str_printf : 成功直接返回
static char * _str_printf(const char * format, va_list arg) {
    char buf[BUFSIZ];
    int len = vsnprintf(buf, sizeof buf, format, arg);
    if (len < sizeof buf) {
        char * ret = malloc(len + 1);
        return memcpy(ret, buf, len + 1);
    }
    return NULL;
}

//
// str_printf - 字符串构建函数
// format   : 构建格式参照pritnf
// ...      : 参数集
// return   : char * 堆上内存
//
char * 
str_printf(const char * format, ...) {
    char * ret;
    int len, cap;
    va_list arg;
    va_start(arg, format);

    // BUFSIZ 以下内存直接分配
    ret = _str_printf(format, arg);
    if (ret != NULL)
        return ret;

    cap = BUFSIZ << 1;
    for (;;) {
        ret = malloc(cap);
        len = vsnprintf(ret, cap, format, arg);
        // 失败的情况
        if (len < 0) {
            free(ret);
            return NULL;
        }

        // 成功情况
        if (len < cap)
            break;

        // 内存不足的情况
        free(ret);
        cap <<= 1;
    }

    return realloc(ret, len + 1);
}
人生 一块开心 最好 : )