☰
C语言多线程编程
2026/10/17 6:44:25 网站建设 项目流程

Linux POSIX 多线程

一、多线程介绍

  • 单线程:程序是一条单行道。一旦阻塞,全盘挂起。不能并发处理其他任务(网络监听、数据读取)。
  • 多线程:允许程序同时执行多个任务
    • 主线程(main):负责板卡初始化、配置文件解析,维持程序常驻保护,响应退出信号
    • 后台工作线程:独立运行在后台(UDP 监听指令、板卡数据采集、DDS网络推送…)

二、POSIX 线程函数规范

在 Linux 中,交给pthread_create执行的线程入口函数要遵循下面格式:

void*thread_func_name(void*pParam);
  • 参数void* pParam:

    • void*是 C/C++ 中的 万能指针。操作系统创建线程时不知道具体业务传递什么数据(整数、结构体、指针),因此按void*传递。
    • 进入线程后,再将 pParam 强转为具体数据类型。
  • 返回值void*:

    • 线程正常结束时若无特殊数据返回,直接return NULL即可。

三、线程生命周期四步

1.创建线程

​ 通知操作系统创建一个新的子线程去跑函数。

#include <pthread.h> /* pthread_t 是 Linux POSIX 线程库中用来标识线程 ID 的数据类型 */ pthread_t tid; // 线程 ID // 创建线程并启动 pthread_create(&tid, NULL, thread_func_name, (void*)&serverSock);
  • &tid:传入pthread_t变量地址,用于接收系统分配的线程 ID。

  • NULL:线程属性,NULL默认属性

  • thread_func_name:线程入口函数名(指针)。

  • (void*)&serverSock:传给子线程函数的参数指针,若无参数可传NULL。

2.编写线程入口函数

​ 线程一旦被创建,会自动进入这个函数执行,一般内部会带有while循环做常驻任务:

// 示例:数据接收线程 void* thread_func_name(void* pParam) { // 1. 将万能指针强转为实际类型 int serverSock = *(int*)pParam; // 2.线程主循环(标志位为真,就继续执行任务) while (g_running) { // 执行具体网络接收或业务处理 // recv(...); usleep(1000); // 休眠 1ms,防止CPU占用率100% } //3.退出线程 return NULL; }

3.回收线程

​ 主线程退出或关闭服务时,需要等待后台子线程安全退出,防止子线程还在跑程序就把内存释放了:

// 1.先通过标志位通知子线程退出循环 g_running = 0; // 2.主线程阻塞等待子线程真正执行完毕并回收资源 pthread_join(tid, NULL);
  • tid:要等待的子线程 ID。

  • NULL:用于接收子线程return的指针,不需要时传NULL。

4.线程同步/锁

​ 如果有多个线程同时读写同一个变量(例如一个线程写数据,另一个线程读数据),为了防止数据错乱,需要加锁:

// 1.定义并初始化互斥锁 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // 2.上锁 pthread_mutex_lock(&lock); // 3.临界区代码(安全地读写共享数据) /* ...... */ // 4.解锁 pthread_mutex_unlock(&lock);

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询