瞭解 "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);
}
人生 一塊開心 最好 : )