线程:同一个程序,不同代码片段的并发运行;父子线程共享内存和变量
线程创建
#include
#include <pthread.h>
using namespace std;
// 线程任务
void* task(void* args) {
cout << “hello world” << endl;
pthread_join(pthread_self());
return 0;
}
int main() {
// 定义线程的 id 变量
pthread_t tid;
//参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数(多个参数使用结构体或数组)
int ret = pthread_create(&tid, NULL, task, NULL);
if (ret != 0) {
cout << "pthread_create error: " << ret << endl;
}
//显式地退出,main等线程退出后,进程才结束,否则main进程结束,线程也跟着结束
pthread_exit(NULL);
}
线程阻塞
1. 阻塞(当前线程阻塞等待被调用的线程结束,才继续往下运行)
int pthread_join(pthread_t thread, void **retval);
args:
pthread_t thread:被连接线程的线程号
void **retval:指向一个指向被连接线程的返回码的指针的指针
return:
线程连接的状态,0是成功,非0是失败。return后线程结束,内存等资源回收。
2. 非阻塞
int pthread_detach(pthread_t thread);
这将该子线程的状态设置为detached,线程结束后会自动释放所有资源。
资源回收
1. 创建线程时需要确定线程的属性为joinable(可连接的)或detached(可分离的),默认的状态是joinable。
2. 设置线程为detached(PTHREAD_CREATE_DETACHED属性)
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 设置分离属性
pthread_create(&tid, &attr, (void*)thread1, NULL);
pthread_attr_destroy(&attr);
3. 如果是joinable,线程结束后不会释放其内存空间,导致该线程变成了“僵尸线程”。需要当前线程调用pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源
4. pthread_detach/pthread_join可以在主线程或子线程调用
简单点说:线程为detached时,调用pthread_detach后不用管;线程为joinable,主线程pthread_join阻塞等待线程结束,再回收资源
线程开始
1. 线程创建后就自动开始运行
2. 创建线程要时间,创建好线程后才运行任务函数,所以不能传递局部变量给任务函数(局部变量可能销毁了)
线程结束
1. 主线程在结束前调用pthread_exit,则主线程结束,进程不结束。进程等待所有线程结束才结束
2. 在任意地方调用exit结束进程,则所有线程都结束
3. 线程取消pthread_cancel
线程库(c++11开始)
#include
#include
using namespace std;
// 线程任务
void task() {
std::thread::id id = std::this_thread::get_id();
cout << “hello world:” << id << endl;
}
// 线程暂停
void pause_thread(int n) {
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << “pause of " << n << " seconds ended\n”;
}
int main() {
std::thread t(task);
t.join();
std::thread a(task);
a.detach();
std::thread threads[5];
for (int i = 0; i < 5; ++i) {
threads[i] = std::thread(pause_thread, i + 1);
}
for (auto &thread : threads)
thread.join();
}
}