1. C语言多线程编程基础
1.1 线程与进程的本质区别
在操作系统层面,线程和进程是两种完全不同的执行实体。理解它们的区别是多线程编程的基础。
进程是操作系统资源分配的基本单位,每个进程都有自己独立的内存空间(包括代码段、数据段、堆栈段等)。当操作系统创建一个新进程时,需要为其分配内存、文件描述符等资源,这个过程开销较大。进程间的通信(IPC)需要通过特定的机制实现,如管道、消息队列、共享内存等。
线程则是进程内的执行单元,一个进程可以包含多个线程。所有线程共享进程的内存空间和资源,包括全局变量、堆内存、文件描述符等。线程的创建和切换开销远小于进程,因为不需要进行内存映射等复杂操作。
从实现角度看,Linux系统中的线程实际上是通过轻量级进程(LWP)实现的,使用相同的系统调用clone()创建,只是参数不同。Windows系统则有专门的线程实现机制。
1.2 POSIX线程库概述
POSIX线程(pthread)是IEEE制定的线程标准接口,被类Unix系统广泛支持。它定义了一组操作线程的函数和数据类型,主要包括:
- 线程管理:创建、终止、等待、属性设置等
- 同步机制:互斥锁、条件变量、读写锁、屏障等
- 线程特定数据:线程局部存储
pthread不是C标准库的一部分,使用时需要链接pthread库。在Linux系统中,pthread的实现位于glibc中,通过系统调用最终由内核调度器管理线程执行。
1.3 第一个多线程程序
下面我们通过一个简单的例子展示如何创建线程:
c复制#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void* thread_func(void* arg) {
printf("子线程开始执行\n");
sleep(2); // 模拟耗时操作
printf("子线程执行结束\n");
return NULL;
}
int main() {
pthread_t tid;
int ret;
printf("主线程开始\n");
// 创建线程
ret = pthread_create(&tid, NULL, thread_func, NULL);
if (ret != 0) {
perror("pthread_create failed");
exit(EXIT_FAILURE);
}
// 等待线程结束
pthread_join(tid, NULL);
printf("主线程结束\n");
return 0;
}
编译时需要加上-pthread选项:
bash复制gcc thread_demo.c -o thread_demo -pthread
这个程序展示了多线程编程的基本流程:
- 定义线程函数(thread_func)
- 使用pthread_create创建线程
- 使用pthread_join等待线程结束
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 线程管理深入解析
2.1 线程创建与参数传递
pthread_create函数的完整原型如下:
c复制int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
参数传递是多线程编程中常见的需求。由于线程函数只能接受一个void*参数,当需要传递多个参数时,通常需要封装成结构体:
c复制struct thread_args {
int id;
const char* name;
};
void* thread_func(void* arg) {
struct thread_args* args = (struct thread_args*)arg;
printf("线程%d: %s\n", args->id, args->name);
free(args); // 释放内存
return NULL;
}
int main() {
pthread_t tid;
struct thread_args* args = malloc(sizeof(struct thread_args));
args->id = 1;
args->name = "测试线程";
pthread_create(&tid, NULL, thread_func, args);
pthread_join(tid, NULL);
return 0;
}
2.2 线程终止方式
线程可以通过以下方式终止:
- 从线程函数return
- 调用pthread_exit
- 被其他线程取消(pthread_cancel)
pthread_exit和return的区别在于:
- pthread_exit可以在任何地方调用,立即终止当前线程
- return只能在线程函数内使用
c复制void* thread_func(void* arg) {
if (some_condition) {
pthread_exit(NULL); // 立即退出
}
// 其他代码
return NULL; // 正常退出
}
2.3 线程属性设置
线程属性允许我们定制线程的行为,常用的属性包括:
- 分离状态(detach state)
- 栈大小(stack size)
- 调度策略和优先级(scheduling policy and priority)
设置线程属性的基本流程:
c复制pthread_attr_t attr;
pthread_attr_init(&attr); // 初始化属性
// 设置分离状态
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACH
