# cutils **Repository Path**: cvincent/cutils ## Basic Information - **Project Name**: cutils - **Description**: C 语言中的工具。 - **Primary Language**: C - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2015-06-13 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README cutils ======== 把一些 Java 里面习惯使用的工具,用 C 来实现。 已实现:LinkedList、BlockingQueue 计划实现:Queue、Stack、ArrayList、HashSet、HashMap、StringBuilder LinkedList -------- 双向链表,可以满足不定数量元素的存放需要。 实现了从头部添加、取出,从末尾添加、取出,迭代器,从指定位置取出、删除功能。 ```C /** * LinkedList 使用样例 */ #include "LinkedList.h" #include #include #include int main(int argc, char** argv) { LINKED_LIST* linked_list; printf("LinkedList Test!\n"); printf("测试初始化链表..\n"); linked_list = linked_list_construct(); printf("往链表中插入 10 个元素...\n"); int i; for(i=0;i<10;i++) { char* message = (char*)malloc(50); memset(message, 0, 50); sprintf(message, "第 [%2d] 个元素", i+1); printf("在链表后添加: %s\n",message); linked_list_offer_last(linked_list, message); } for(i=0;i<10;i++) { char* message = NULL; linked_list_get(linked_list, i, &message, 0); printf("链表中第 [%2d] 个元素: %s\n",i, message); } for(i=0;i<10;i++) { char* message = NULL; linked_list_poll_first(linked_list, &message); printf("在链表头删除: %s\n",message); free(message); } for(i=0;i<10;i++) { char* message = (char*)malloc(sizeof(char)*50); memset(message, 0, 50); sprintf(message, "第 [%2d] 个元素", i+1); printf("在链表头添加: %s\n",message); linked_list_offer_first(linked_list, message); } for(i=0;i<10;i++) { char* message = 0; linked_list_poll_last(linked_list, &message); printf("在链表后删除: %s\n",message); free(message); } linked_list_destroy(linked_list); return 0; } ``` BlockingQueue -------- 基于链表的阻塞队列,主要用于多线程之间协调工作,常见于生产者与消费者模式。 构造时通过参数指定队列是否有容量限制,若参数为0则为没有容量限制。 put方法往队列末尾添加元素,若队列有容量限制,在达到上限时,调用线程会被挂起等待,直到队列中有元素被取走,或队列被销毁为止。 take方法从队列头部取出元素,若队列为空,则调用线程会被挂起等待,直到队列中放入新元素,或队列被销毁为止。 ```C /* * BlockingQueue 使用样例 */ #include "BlockingQueue.h" #include #include #include #include #include #include #include void log(char* format, ...) { va_list argp; va_start(argp, format); struct timeb tp; struct tm * tm; ftime(&tp); tm = localtime(&(tp.time)); char log_time[20]; memset(log_time, 0, sizeof(log_time)); sprintf(log_time, "%02d:%02d:%02d.%03d", (tm->tm_hour), (tm->tm_min) ,(tm->tm_sec), (tp.millitm)); pthread_t thread_id = pthread_self(); char log_message[1000]; memset(log_message, 0, sizeof(log_message)); vsprintf(log_message, format, argp); printf("[%s][%p] %s\n", log_time, (void*) thread_id, log_message); va_end(argp); } void put_message(void* arg) { pthread_t thread_id = pthread_self(); BLOCKING_QUEUE* blocking_queue = (BLOCKING_QUEUE*)arg; int i; for(i=0;i<4;i++) { char* message = malloc(sizeof(char)*100); memset(message, 0, 100); sprintf(message, "测试消息 [%p][%d]!", (void*)thread_id, i); log("□->开始往队列添加消息: 当前队列长度=%2d, %s", blocking_queue->item_list->length, message); blocking_queue_put(blocking_queue, message); log("■->完成往队列添加消息: 当前队列长度=%2d, %s", blocking_queue->item_list->length, message); sleep(5); } log("停止往队列添加消息。"); pthread_exit(0); } void take_message(void* arg) { BLOCKING_QUEUE* blocking_queue = (BLOCKING_QUEUE*)arg; int i; for(i=0;i<2;i++) { char* message = NULL; log("□<-开始从队列取出消息: 当前队列长度=%2d", blocking_queue->item_list->length); blocking_queue_take(blocking_queue, &message); log("■<-完成从队列取出消息: 当前队列长度=%2d, %s", blocking_queue->item_list->length, message); free(message); sleep(2); } log("停止从队列取出消息。"); pthread_exit(0); } int set_pthread_attr(pthread_attr_t* pthread_attr) { pthread_attr_init(pthread_attr); if((pthread_attr_setschedpolicy(pthread_attr, SCHED_RR) !=0 )) { log("设置线程调度策略 SCHED_RR 失败!"); return 1; } if((pthread_attr_setdetachstate(pthread_attr, PTHREAD_CREATE_DETACHED) !=0 )) { log("设置线程分离属性 PTHREAD_CREATE_DETACHED 失败!"); return 1; } return 0; } int create_thread(pthread_t* thread_id, void *(*func) (void *), void *arg) { int err; pthread_attr_t thread_attr; err = set_pthread_attr(&thread_attr); if(err!=0) return err; err = pthread_create(thread_id, &thread_attr, func, arg); pthread_attr_destroy(&thread_attr); return err; } int create_put_message_thread(BLOCKING_QUEUE* blocking_queue, LINKED_LIST* put_message_thread_list) { int err; pthread_t* thread_id = (pthread_t*)malloc(sizeof(pthread_t)); err = create_thread(thread_id, put_message, blocking_queue); if(err!=0) { log("创建添加消息线程出错!"); return err; } linked_list_offer_last(put_message_thread_list, thread_id); return 0; } int create_take_message_thread(BLOCKING_QUEUE* blocking_queue, LINKED_LIST* take_message_thread_list) { int err; pthread_t* thread_id = (pthread_t*)malloc(sizeof(pthread_t)); err = create_thread(thread_id, take_message, blocking_queue); if(err!=0) { log("创建取出消息线程出错!"); return err; } linked_list_offer_last(take_message_thread_list, thread_id); return 0; } int main(int argv, char** argc) { LINKED_LIST* put_message_thread_list; LINKED_LIST* take_message_thread_list; BLOCKING_QUEUE* blocking_queue; blocking_queue = blocking_queue_construct(10); put_message_thread_list = linked_list_construct(); take_message_thread_list = linked_list_construct(); int i, err; for(i=0;i<4;i++) { err = create_put_message_thread(blocking_queue, put_message_thread_list); if(err!=0) exit(err); } sleep(18); for(i=0;i<10;i++) { err = create_take_message_thread(blocking_queue, take_message_thread_list); if(err!=0) exit(err); } sleep(60); while(put_message_thread_list->length > 0) { pthread_t* thread_id; linked_list_poll_first(put_message_thread_list, (void**)(&thread_id)); log("释放添加消息线程资源: %p", (void*)thread_id); free(thread_id); } while(take_message_thread_list->length > 0) { pthread_t* thread_id; linked_list_poll_first(take_message_thread_list, (void**)(&thread_id)); log("释放取出消息线程资源: %p", (void*)thread_id); free((void*)thread_id); } linked_list_destroy(put_message_thread_list); linked_list_destroy(take_message_thread_list); blocking_queue_destroy(blocking_queue); log("程序结束。"); return 0; } ```