一、C语言线程创建(POSIX线程)
1. 基本创建方法
POSIX线程(pthread)是C语言中创建线程的标准API:
#include <pthread.h>
#include <stdio.h>
void* thread_func(void* arg) {
printf("Thread running with arg: %d\n", *(int*)arg);
return NULL;
}
int main() {
pthread_t tid;
int arg = 42;
// 创建线程
int ret = pthread_create(&tid, NULL, thread_func, &arg);
if (ret != 0) {
perror("pthread_create failed");
return 1;
}
// 等待线程结束
pthread_join(tid, NULL);
return 0;
}
2. 关键参数说明
pthread_t *thread
:存储线程ID的指针const pthread_attr_t *attr
:线程属性(NULL表示默认)void *(*start_routine)(void*)
:线程函数指针void *arg
:传递给线程函数的参数
3. 线程属性设置
pthread_attr_t attr;
pthread_attr_init(&attr); // 初始化属性
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 设置分离属性
pthread_create(&tid, &attr, thread_func, NULL);
pthread_attr_destroy(&attr); // 销毁属性对象
二、C++线程创建(std::thread)
1. 基本创建方法
C++11引入了std::thread
类简化线程创建:
#include <iostream>
#include <thread>
void thread_function() {
std::cout << "Thread function executing" << std::endl;
}
int main() {
// 创建并启动线程
std::thread t(thread_function);
// 等待线程结束
t.join();
return 0;
}
2. 多种创建方式
(1) 使用函数指针
void print_message(const std::string& msg) {
std::cout << msg << std::endl;
}
std::thread t1(print_message, "Hello from thread");
(2) 使用Lambda表达式
std::thread t2(:ml-search[]{
std::cout << "Lambda thread running" << std::endl;
});
(3) 使用成员函数
class MyClass {
public:
void member_func() {
std::cout << "Member function thread" << std::endl;
}
};
MyClass obj;
std::thread t3(&MyClass::member_func, &obj);
3. 线程管理
join()
:等待线程结束detach()
:分离线程(后台运行)joinable()
:检查线程是否可join
三、C与C++线程创建对比
特性 | std::thread (C++11) | pthread (POSIX) |
---|---|---|
标准化程度 | C++标准库的一部分 | POSIX标准,非C++原生 |
跨平台性 | 所有支持C++11的平台 | 主要类UNIX系统 |
接口风格 | 面向对象(类+成员函数) | C风格函数接口 |
线程创建 | 构造函数直接启动线程 | 需显式调用pthread_create |
参数传递 | 类型安全,支持任意可调用对象 | 需通过void*指针强制转换 |
资源管理 | RAII自动管理(析构自动处理) | 需手动调用pthread_join/detach |
错误处理 | 异常机制 | 返回值错误码 |
头文件 | <thread> |
<pthread.h> |
编译要求 | 需支持C++11 | 需链接-lpthread 库 |
四、实际应用示例
1. 多线程计算(C++)
#include <iostream>
#include <thread>
#include <vector>
void compute(int start, int end, int& result) {
int sum = 0;
for (int i = start; i <= end; ++i) {
sum += i;
}
result = sum;
}
int main() {
const int n = 1000;
int result1, result2;
std::thread t1(compute, 1, n/2, std::ref(result1));
std::thread t2(compute, n/2+1, n, std::ref(result2));
t1.join();
t2.join();
std::cout << "Total sum: " << result1 + result2 << std::endl;
return 0;
}
2. 线程池基础(C)
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define THREAD_COUNT 4
void* worker(void* arg) {
int id = *(int*)arg;
printf("Worker %d started\n", id);
// 实际工作任务...
printf("Worker %d finished\n", id);
return NULL;
}
int main() {
pthread_t threads[THREAD_COUNT];
int thread_ids[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; ++i) {
thread_ids[i] = i;
pthread_create(&threads[i], NULL, worker, &thread_ids[i]);
}
for (int i = 0; i < THREAD_COUNT; ++i) {
pthread_join(threads[i], NULL);
}
return 0;
}
五、注意事项
- 资源管理:C++的std::thread使用RAII,析构时若未join/detach会terminate
- 参数生命周期:确保线程参数在线程使用期间有效
- 线程安全:共享数据需要同步机制(mutex等)
- 错误处理:C++使用异常,C检查返回值
- 平台差异:pthread在不同Unix-like系统实现可能不同
六、使用建议
优先使用std::thread的情况:
- 开发跨平台应用
- 需要与C++其他特性(如lambda、智能指针)集成
- 希望简化资源管理
- 项目已使用C++11或更高标准
可能需要使用pthread的情况:
- 维护遗留代码
- 需要特定POSIX线程特性(如优先级控制)
- 在仅支持C的嵌入式环境中开发
- 需要精细控制线程属性(虽然C++11也可通过native_handle实现)
七、性能注意事项
在主流平台上,两者性能差异通常小于%5,因为:
std::thread
在Linux上实质是pthread的封装- 线程创建/切换等核心操作最终都调用相同的系统API
实际选择应更多考虑:
- 代码可维护性
- 与现有代码库的整合度
- 团队熟悉程度
- 长期维护成本