当前位置:网站首页>C语言实现一种创建易管理易维护线程的方法
C语言实现一种创建易管理易维护线程的方法
2022-06-29 09:10:00 【水似冰】
一、什么是线程?
在一个程序中的多个执行路线就叫做线程。
就个人理解而言,一个线程就是一个进程里的一个while(1),一般情况下线程是不会退出的。
而多线程自然就是一个进程里的多个while(1)了。
《西游记》中,有一种有趣的设定——“天上一天,地上一年”。
而在现实世界中,随着技术发展,CPU的性能越来越高,夸张点说:“CPU一年,地上一天”。
为了高效利用CPU性能,多进程的方式丰富了操作系统,无论是windows还是Linux系统,程序都是“轮班”跑的,放慢些看,就是这个运行一会儿,然后让出CPU,其他程序再运行一会儿,然而我们看起来就是同时运行的。
多线程也是这样的。
二、linux下线程函数
Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,在编译时注意加上-lpthread参数,以调用静态链接库;pthread并非Linux系统的默认库
1、pthread_create
- pthread_create是UNIX环境创建线程函数
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg);- 若成功则返回0,否则返回错误码
- 第一个参数为指向线程标识符的指针;二个参数用来设置线程属性;第三个参数是线程运行函数的地址;最后一个参数是运行函数的参数
2、pthread_join
- 函数pthread_join用来等待一个线程的结束
extern int pthread_join __P (pthread_t __th, void **__thread_return);- 如果执行成功,将返回0,失败则返回错误码
- 第一个参数为被等待的线程标识符;第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
- 这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回
#include <stdio.h>
#include <pthread.h>
void *threadfun(void *arg)
{
printf("hello \n");
}
int main(void)
{
pthread_t id;
int i,ret;
ret=pthread_create(&id,NULL,threadfun,NULL);
if(ret!=0) {
printf ("Create pthread error!\n");
exit (1);
}
pthread_join(id,NULL);
return (0);
} 补充: printf("current thread id:%u\n", (unsigned int)pthread_self());可打印出当前线程id。
三、创建易管理易维护的线程
文件均为为给力同事所传。为防丢失忘记,因此记录于此。
1、优势:
- 可设置优先级
- 易查看
2、使用
在工程中加入下面的c文件和h文件。
包头文件,然后这样创建:
static int port = 14000;
printf("current thread id:%u\n", (unsigned int)pthread_self());
ThreadCreateParaDef tThreadCreatePara;
memset(&tThreadCreatePara, 0, sizeof(ThreadCreateParaDef));
tThreadCreatePara.ps8Name = (char *)"receiveJobs";
tThreadCreatePara.pvFuncPara = &port;
tThreadCreatePara.EntryFuncPt = gSoapServerThread;
createThread(&tThreadCreatePara);3、查看步骤
ps -ef | grep fw_ro* 查看进程id
top -H -p 16002查看进程的线程,效果如下图:
PID为29527的线程即为receiveJobs线程。 
4、附录
cbasethread.h
#ifndef CBAETHREAD_H
#define CBAETHREAD_H
typedef struct ThreadCreateParaDef
{
char *ps8Name; // 线程名称
void *(*EntryFuncPt)(void *); // 线程入口函数
void *pvFuncPara; // 线程参数
int s32OldCancelState;
int s32OldCancelType;
}ThreadCreateParaDef;
int CreateThread(ThreadCreateParaDef *ptThreadCreatePara);
#endif // MSG_DISTRIBUTION_Hcbasethread.c
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/prctl.h>
#include "cbasethread.h"
void *ThreadInterface(void *pvPara)
{
ThreadCreateParaDef *ptThreadCreatePara = (ThreadCreateParaDef *)pvPara;
void *pvFuncPara = ptThreadCreatePara->pvFuncPara;
/* 设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省) 和PTHREAD_CANCEL_DISABLE,分别表示收到信号后设为CANCLED状态和忽略CANCEL信 号继续运行;old_state如果不为NULL则存入原来的Cancel状态以便恢复。 */
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ptThreadCreatePara->s32OldCancelState);
/* 设置本线程取消动作的执行时机,type有两种取值:PTHREAD_CANCEL_DEFERRED和 PTHREAD_CANCEL_ASYNCHRONOUS,仅当Cancel状态为Enable时有效,分别表示收到 信号后继续运行至下一个取消点再退出和立即执行取消动作(退出);oldtype如 果不为NULL则存入运来的取消动作类型值。 */
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &ptThreadCreatePara->s32OldCancelType);
prctl(PR_SET_NAME, ptThreadCreatePara->ps8Name);
if(NULL != pvPara)
{
free(pvPara);
}
(*ptThreadCreatePara->EntryFuncPt)(pvFuncPara);
return NULL;
}
pthread_t TaskSpawn
(
char *ps8Name, /* 任务的名称 */
int s32Priority, /* 实时任务的优先级 1-99 */
void *(*pvEntryPt)(void *), /* 任务的函数入口 */
void *pvFuncPara, /* 这是一个指针值,任务入口函数的入参 */
int s32Schedule /*指定fifo 、rr或者normal调度方法*/
)
{
int ret = 0;
struct sched_param tSchParam;
pthread_attr_t tThreadAttr;
pthread_t tThreadID;
int s32SchPolicy;
if(NULL == pvEntryPt)
{
return 0;
}
/*判断优先级的正确性*/
if (s32Priority > 99 || s32Priority < 0)
{
return 0;
}
/*初始化线程参数*/
pthread_attr_init(&tThreadAttr);
/*设置调度策略*/
pthread_attr_getschedpolicy(&tThreadAttr, &s32SchPolicy);
s32SchPolicy = s32Schedule; /*创建的所有任务都将是实时任务*/
pthread_attr_setschedpolicy(&tThreadAttr, s32SchPolicy);
/*设置进程为分离状态,任务分离后将不需要用pthread_join()等待线程退出*/
pthread_attr_setdetachstate(&tThreadAttr, PTHREAD_CREATE_DETACHED);
if (SCHED_FIFO == s32Schedule || SCHED_RR == s32Schedule)
{
/* 设置实时任务的优先级*/
pthread_attr_getschedparam(&tThreadAttr, &tSchParam);
tSchParam.sched_priority = s32Priority;
pthread_attr_setschedparam(&tThreadAttr, &tSchParam);
}
ret = pthread_create(&tThreadID, &tThreadAttr, pvEntryPt, pvFuncPara);
if(0 != ret)
{
perror(NULL);
printf("TaskSpawn-%s create error", ps8Name);
return 0;
}
return tThreadID;
}
int CreateThread(ThreadCreateParaDef *ptThreadCreatePara)
{
pthread_t tThreadSysID;
ThreadCreateParaDef *pthreadPara = NULL;
pthreadPara = (ThreadCreateParaDef *)malloc(sizeof(ThreadCreateParaDef));
memcpy(pthreadPara, ptThreadCreatePara, sizeof(ThreadCreateParaDef));
tThreadSysID = TaskSpawn(ptThreadCreatePara->ps8Name, 1, ThreadInterface, pthreadPara, SCHED_RR);
if(!tThreadSysID) // 线程启动有问题
{
printf("Thread startup error\n");
if (pthreadPara != NULL)
{
free(pthreadPara);
}
return -1;
}
return 0;
}
边栏推荐
- es报错NoNodeAvailableException[None of the configured nodes are available:[.127.0.0.1}{127.0.0.1:9300]
- Chapter 12 signals (II) - examples of producers and consumers
- 指针函数和函数指针
- 数据治理:数据标准管理(第三篇)
- 【NOI模拟赛】为NOI加点料(重链剖分,线段树)
- [noi Simulation Competition] add points for noi (heavy chain dissection, line segment tree)
- Official STM32 chip package download address stm32f10x stm32f40x Download
- Reading notes on how to connect the network - Web server request and response (V)
- 1.4 regression of machine learning methods
- 监控数据源连接池使用情况
猜你喜欢

Closed training (25) basic web security

自定义mvc框架实现

UE4 animation redirection

Five heart charity matchmaker team

Generic paging framework

Lc236. nearest common ancestor of binary tree

Introduction to Chang'an chain data storage and construction of MySQL storage environment

基于PyQt5和Qt Designer的简易加法计算器的制作

MATLAB小技巧(21)矩阵分析--偏最小二乘回归

数据治理:数据标准管理(第三篇)
随机推荐
UE4 material UV texture does not stretch with model scale
数据源连接池未关闭的问题 Could not open JDBC Connection for transaction
云管理平台:9大开源云管理平台(CMP)
2020-09-23左右值 右值引用 std::move()
Data governance: the solution of data governance in the data Arena
MySQL configuring master-slave databases
Deep Learning-based Automated Delineation of Head and Neck Malignant Lesions from PET Images
[noi Simulation Competition] add points for noi (heavy chain dissection, line segment tree)
滑块验证代码
2020-09-17 gateway业务流程 两个任务:referer认证和非商品模板化
GD32F4xx 以太網芯片(enc28j60)驅動移植
Visual assist plug-in settings for UE4 vs
Basic operations of MAC MySQL database
監控數據源連接池使用情况
1424. diagonal traversal II
Mac mysql数据库基本操作
Fully Automated Delineation of Gross Tumor Volume for Head and Neck Cancer on PET-CT Using Deep Lear
Fabrication d'une calculatrice d'addition simple basée sur pyqt5 et Qt Designer
基于keil5自动配置stm32f103标准库的官网freertos移植
MySQL modify auto increment initial value