前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言链表应用--基于Linux C多线程软件框架实现

C语言链表应用--基于Linux C多线程软件框架实现

作者头像
杨源鑫
发布2019-07-04 15:46:45
2.4K0
发布2019-07-04 15:46:45
举报
文章被收录于专栏:嵌入式开发圈嵌入式开发圈

之前写过一篇基于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,通过宏定义来调用,也可以调用子函数,宏定义使用起来非常简单方便,但可拓展性不高,程序员可以根据自己的需求去自己定义宏函数,而实际子函数使用起来则会更加灵活,可自己定制。

代码语言:javascript
复制
#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 <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> 
#include <assert.h>
#include <pthread.h>
#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!\n");
 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!\n");
 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\n");
 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、调度任务运行

测试使用:test.c

代码语言:javascript
复制
#include<stdio.h>
#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:

代码语言:javascript
复制
 {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、定义头指针,初始化头节点

代码语言:javascript
复制
 INIT_WORK(work_node);
 for(i = ZERO ; i < NR(work_Register) ; i++) 
 {

//2、实现工作任务的注册

代码语言:javascript
复制
 REGISTER_WORK(work_node , create_cwork(work_Register[i].work_num ,work_Register[i].work_name , work_Register[i].work_handler));
 }

//3、调度工作任务,编号从小到大排序

代码语言:javascript
复制
 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) 
{
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式开发圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档