基于Linux C多线程软件框架实现

2019-07-12 17:39发布

之前写过一篇基于C语言链表实现的工作任务注册与执行,链接如下:https://blog.csdn.net/morixinguan/article/details/77986553后面使用它演变成为了另外一个框架,也就是多线程,当时的设计思路主要是为了服务测试程序。搞过RK(瑞芯微)平台的都知道,这个平台提供了一个PCBA的测试程序,它是基于Linux内核链表框架实现的,但该程序有一点不好的地方就在于框架用起来不是那么的简单,因此我针对该项目做了自己的优化,使之用起来简单,可定制性也高,程序在百度应该可以搜索得到。RK PCBA实现效果:https://wenku.baidu.com/view/09257cb777a20029bd64783e0912a21615797f58.html我实现的项目具体的数据类型以及数据结构:typedef unsigned char u8 ; typedef unsigned int u32; typedef unsigned short u16; typedef char s8 ; typedef int s32; typedef short s16; typedef char * pchar; typedef int * pint ; typedef short * pshort ; typedef void No_return; typedef void (*work_fun)(); #define SUCCESS 0 #define ZERO 0 #define ERROR -1 #define Not_sorted -1 #define Positive 1 #define Reverse 0 typedef struct __Work { //任务编号 //根据任务编号决定工作任务的优先级 //编号越小,优先级越高 s32 work_num ; //任务名称 pchar work_name ; //根据相应的任务名称,处理相应的任务 void (*work_handler)(int); struct __Work *next ; }work; typedef work * _work ;使用的API,通过宏定义来调用,也可以调用子函数,宏定义使用起来非常简单方便,但可拓展性不高,程序员可以根据自己的需求去自己定义宏函数,而实际子函数使用起来则会更加灵活,可自己定制。#define __INIT_WORK(_work) do { _work = Init_cwork(_work); } while (0) #define INIT_WORK(work_node) _work work_node = NULL ; __INIT_WORK(work_node); #define REGISTER_WORK(__work,new_work) Register_work_fuc(__work,new_work); #define SCHEDULING_WORK(work_node,direction,array_size) Run_Priority_work(work_node,direction,array_size); #define DESTROY_WORK(work_node,array) work_node = Destroy_work(work_node ,array); //初始化一个子任务 _work Init_cwork(); //创建一个子任务 _work create_cwork(s32 work_num,pchar work_name ,work_fun work_fuc) ; //注册子任务 No_return Register_work_fuc(_work __work,_work new_work); //查找子任务的编号 s32 Find_Work_Num(_work headler,s32 work_num); //查找子任务的名称 pchar Find_Work_Name(_work headler,pchar work_name) ; //执行子任务----根据任务名称来执行 s32 Run_work_for_work_name(_work headler,pchar work_name) ; //销毁一个子任务 s32 Destroy_cwork(_work headler,pchar work_name); //销毁全部任务 _work Destroy_work(_work headler,_work array); //工作优先级调度执行--->工作编号小的优先级高,依次类推 s32 Run_Priority_work(_work handler,s32 direction,const s32 work_array_size) ;具体实现如下: work.h#ifndef __WORK_H #define __WORK_H #include #include #include #include #include #include #define NR(x) (sizeof(x)/sizeof(x[0])) typedef unsigned char u8 ; typedef unsigned int u32; typedef unsigned short u16; typedef char s8 ; typedef int s32; typedef short s16; typedef char * pchar; typedef int * pint ; typedef short * pshort ; typedef void No_return; typedef void (*work_fun)(); #define SUCCESS 0 #define ZERO 0 #define ERROR -1 #define Not_sorted -1 #define Positive 1 #define Reverse 0 typedef struct __Work { //任务编号 //根据任务编号决定工作任务的优先级 //编号越小,优先级越高 s32 work_num ; //任务名称 pchar work_name ; //根据相应的任务名称,处理相应的任务 void (*work_handler)(int); struct __Work *next ; }work; typedef work * _work ; #define __INIT_WORK(_work) do { _work = Init_cwork(_work); } while (0) #define INIT_WORK(work_node) _work work_node = NULL ; __INIT_WORK(work_node); #define REGISTER_WORK(__work,new_work) Register_work_fuc(__work,new_work); #define SCHEDULING_WORK(work_node,direction,array_size) Run_Priority_work(work_node,direction,array_size); #define DESTROY_WORK(work_node,array) work_node = Destroy_work(work_node ,array); //初始化一个子任务 _work Init_cwork(); //创建一个子任务 _work create_cwork(s32 work_num,pchar work_name ,work_fun work_fuc) ; //注册子任务 No_return Register_work_fuc(_work __work,_work new_work); //查找子任务的编号 s32 Find_Work_Num(_work headler,s32 work_num); //查找子任务的名称 pchar Find_Work_Name(_work headler,pchar work_name) ; //执行子任务----根据任务名称来执行 s32 Run_work_for_work_name(_work headler,pchar work_name) ; //销毁一个子任务 s32 Destroy_cwork(_work headler,pchar work_name); //销毁全部任务 _work Destroy_work(_work headler,_work array); //工作优先级调度执行--->工作编号小的优先级高,依次类推 s32 Run_Priority_work(_work handler,s32 direction,const s32 work_array_size) ; #endif //__WORK_H work.c#include "work.h" _work Init_cwork() { _work handler = NULL ; handler = malloc(sizeof(work)) ; assert(handler != NULL); memset(handler,ZERO,sizeof(work)); handler->work_num = 0 ; handler->work_name = NULL ; handler->work_handler = NULL ; handler->next = NULL ; return handler ; } _work create_cwork(s32 work_num , pchar work_name, work_fun work_fuc) { _work handler = NULL ; handler = malloc(sizeof(work)) ; assert(handler != NULL); memset(handler,ZERO,sizeof(work)); handler->work_num = work_num ; handler->work_name = work_name ; handler->work_handler = work_fuc ; handler->next = NULL ; return handler ; } No_return Register_work_fuc(_work __work,_work new_work) { assert(__work != NULL); _work work_handler = __work ; while(NULL != work_handler->next) work_handler = work_handler->next ; work_handler->next = new_work ; } s32 Find_Work_Num(_work headler,s32 work_num) { assert(headler != NULL); _work temp = headler->next ; while(NULL != temp->next) { if(temp->work_num == work_num) return temp->work_num ; temp = temp->next; } return temp->work_num ; } pchar Find_Work_Name(_work headler,pchar work_name) { assert(headler != NULL); _work temp = headler->next ; while(NULL != temp->next) { if(temp->work_name == work_name) return temp->work_name ; temp = temp->next; } return temp->work_name ; } s32 Run_work_for_work_name(_work headler,pchar work_name) { assert(headler != NULL); pthread_t tid ; s32 ret ; _work temp = headler ; while(NULL != temp->next) { temp = temp->next; if(temp->work_name == work_name){ //创建线程 ret = pthread_create(&tid , NULL , (void *)temp->work_handler , temp->work_name); if(ret != SUCCESS){ perror("create pthread fail"); return ERROR ; } //线程分离 ret = pthread_detach(tid); return SUCCESS; } } if(temp->work_name == work_name){ ret = pthread_create(&tid , NULL , (void *)temp->work_handler , temp->work_name); if(ret != SUCCESS){ perror("create pthread fail"); return ERROR ; } ret = pthread_detach(tid); return SUCCESS ; } printf("not this work , return ERROR! "); return ERROR; } static s32 Run_work_for_work_num(_work headler,s32 work_num) { assert(headler != NULL); pthread_t tid ; s32 ret ; _work temp = headler ; while(NULL != temp->next) { temp = temp->next; if(temp->work_num == work_num){ //创建线程 ret = pthread_create(&tid , NULL , (void *)temp->work_handler , temp->work_num); if(ret != SUCCESS){ perror("create pthread fail"); return ERROR ; } //线程分离 ret = pthread_detach(tid); return SUCCESS; } } if(temp->work_num == work_num){ ret = pthread_create(&tid , NULL , (void *)temp->work_handler , temp->work_num); if(ret != SUCCESS){ perror("create pthread fail"); return ERROR ; } ret = pthread_detach(tid); return SUCCESS ; } printf("not this work , return ERROR! "); return ERROR; } static No_return Sort_work_num(s32 *buf, s32 len ,int direction) { s32 min; s32 index; s32 i, j , n; if(direction == Positive) { for(i = ZERO; i < len - 1; i++) { min = buf[i]; index = i; for(j = i; j < len; j++) { if(buf[j] < min) { min = buf[j]; index = j; } } buf[index] = buf[i]; buf[i] = min; } } else if(direction == Reverse) { for(i = 0 ; i < len ; i++) { for(j = 0 ; j < len ; j++) { if(buf[i] < buf[i+1]) { n = buf[i] ; buf[i] = buf[i+1] ; buf[i+1] = n ; } } } } else { return ; } } s32 Run_Priority_work(_work handler,s32 direction,const s32 work_array_size) { s32 count = 0 ; s32 i ; assert(handler != NULL); _work temp = handler->next ; s32 Curent_node_Array[work_array_size]; while(temp != NULL){ Curent_node_Array[count] = temp->work_num ; temp = temp->next ; if(count < work_array_size) count++ ; } Sort_work_num(Curent_node_Array,NR(Curent_node_Array),direction) ; for(i = 0 ; i < NR(Curent_node_Array) ; i++) Run_work_for_work_num(handler,Curent_node_Array[i]); return SUCCESS ; } s32 Destroy_cwork(_work headler,pchar work_name) { assert(headler != NULL); _work temp = headler ; _work temp_header_prev = NULL ; while(NULL != temp->next) { temp_header_prev = temp ; temp = temp->next ; if(temp->work_name == work_name) { if(temp->next != NULL) { temp_header_prev->next = temp->next ; free(temp); temp = NULL ; } else { temp_header_prev->next = NULL ; free(temp); temp = NULL ; } return SUCCESS ; } } printf("Not Work node "); return ERROR ; } _work Destroy_work(_work headler,_work array) { s32 i ; assert(headler != NULL); _work temp = headler ; for(i = ZERO ; i < NR(array) ; i++) Destroy_cwork(headler,array[i].work_name); headler = NULL ; return headler ; } 如何使用?1、初始化工作2、工作任务注册3、调度任务运行#include #include "work.h" int Test1(int work_num) ; int Test2(int work_num) ; int Test3(int work_num) ; int Test4(int work_num); int Test5(int work_num); //结构体描述: /* ep: {1,"Test1",Test1}, 1表示任务编号,同时也表示在LCD的哪一行进行显示 "LCD_Test"表示任务名称 LCD_Test表示任务执行函数 */ work work_Register[] = { {1,"Test1",Test1}, {2,"Test1",Test2}, {3,"Test3",Test3}, {4,"Test4",Test4}, {5,"Test5",Test5}, }; int main(void) { s32 i ; //1、定义头指针,初始化头节点 INIT_WORK(work_node); for(i = ZERO ; i < NR(work_Register) ; i++) { //2、实现工作任务的注册 REGISTER_WORK(work_node , create_cwork(work_Register[i].work_num ,work_Register[i].work_name , work_Register[i].work_handler)); } //3、调度工作任务,编号从小到大排序 SCHEDULING_WORK(work_node,Positive,NR(work_Register)); while(True) { ; } //DESTROY_WORK(work_node,work_Register); return SUCCESS ; } int Test1(int work_num) { } int Test2(int work_num) { } int Test3(int work_num) { } int Test4(int work_num) { } int Test5(int work_num) { } 当然程序可以进一步的优化和定制,在目前看来,该框架可以完全满足我目前的要求,非常稳定且易于维护和拓展。