在Linux C应用中,一般使用进程管理多任务应用;不过对于单片机或windows平台开发者,肯定更熟悉的是多线程应用。对于Linux平台,也同样提供了线程管理接口。
对于多线程来说,优先选择标准C库<threads.h>提供的接口,这部分可参考:
不过对于Linux C本身的接口,也可以进行学习参考,这部分将在本章节进行详细说明。
在Linux C环境中,C语言的线程管理遵循POSIX标准,定义在<pthread.h>头文件中,在编译时需要使用-pthread选项进行链接。
对于线程管理相关接口,具体如下所示。
对于上述接口,其中常用的接口详细描述如下所示。
// 创建线程// @param thread: 线程标识符// @param attr: 线程属性,传递NULL表示默认属性// @param start_routine: 线程运行的函数指针// @param arg: 线程运行函数的参数// @return: 0表示成功,非0表示失败intpthread_create(pthread_t *thread, constpthread_attr_t *attr, void *(*start_routine)(void *), void *arg);// 线程退出// @param value: 线程退出的返回值voidpthread_exit(void *value);// 等待线程结束// @param thread: 线程标识符// @param value: 线程退出的返回值指针// @return: 0表示成功,非0表示失败intpthread_join(pthread_t thread, void **value_ptr);// 线程取消// @param thread: 线程标识符// @return: 0表示成功,非0表示失败intpthread_cancel(pthread_t thread);// 线程分离// @param thread: 线程标识符// @return: 0表示成功,非0表示失败intpthread_detach(pthread_t thread);对于创建线程的接口,其中需要额外讲解的参数就是pthread_attr_t结构体,该结构体用于设置线程属性,具体如下所示。
structsched_param {int sched_priority; // 线程优先级};structpthread_attr_t{unsigned p_state; // 线程状态void *stack; // 线程栈size_t s_size; // 线程栈大小structsched_paramparam;// 线程调度参数};对于线程属性的结构体,同样提供了一组接口进行管理,具体如下所示。
这些属性接口,可以用于更细致化的控制线程的行为,如设置栈地址、栈大小、线程优先级。不过一般情况下,可以使用NULL作为属性attr的输入,表示使用默认的参数,如默认栈大小、默认优先级等,基本满足大多数应用的需求。
线程管理应用主要就是创建线程、等待线程结束、取消线程、线程分离、获取线程标识符,具体应用示例如下所示。
#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<unistd.h>staticvolatileint g_i = 0;// 线程函数void *thread_func(void *arg){int init_val = *((int *)arg); g_i = init_val;printf("thread_func init val: %d\n", init_val);for (int i = 0; i < 10; i++) {printf("thread_func: %d\n", g_i); g_i++; }// 退出线程,返回结果值// 此处强制转换为指针作为返回值 pthread_exit((int *)g_i);}intmain(int argc, char *argv[]){pthread_t tid;pthread_attr_t attr;structsched_paramparam;void * result = NULL; param.sched_priority = 100;int init_val = 2;// 初始化线程属性 pthread_attr_init(&attr); pthread_attr_setschedparam(&attr, ¶m);// 创建线程if(pthread_create(&tid, &attr, thread_func, (void *)&init_val) != 0) {printf("pthread_create error\n");exit(-1); } pthread_join(tid, &result);// 打印线程返回的结果printf("main: %d, result: %d\n", g_i, (int)result);return0;}关于上述代码,具体执行结果如下所示。

多线程管理接口,可以看作对于Linux C多任务应用的补充。通过线程创建、等待、取消、分离、获取线程标识符等接口,可以在Linux平台实现多任务处理,并获取线程的运行结果。
线程是CPU任务调度的最小单位,多个线程之间共享空间、通讯高效,创建线程的开销也更小。不过多线程的程序,当发生崩溃时,所有线程都会被终止。
在实践中,则要根据具体的应用场景,合理选择和进程或线程方法进行处理,才是多线程应用的最佳实践。