1.创建线程 -- pthread
表头文件 | #include <pthread.h> |
定义函数 | int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg); |
函数说明 | 参数: thread: 传出参数,线程创建成功后会被设置一个合适的值,线程ID(无符号长整形); attr:线程属性,默认传NULL;(通过属性设置线程分离:见补充1) start_routine:线程处理函数 arg:线程处理回调函数的参数 |
返回值 | 调用成功新线程的指针会被存储到thread的参数中,并返回0,失败返回错误号; 如果返回EAGAIN,没有足够的系统资源创建一个线程,或者已经存在大于PTHREAD_THREADS_MAX个活跃线程。 |
#include <iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
void* myfunc(void*) {
//打印子线程的id
cout << "Child thread id : "<< pthread_self() << endl;
return NULL;
}
int main(int argc,const char* argv[])
{
//创建一个子线程
//线程id变量
pthread_t pthid;
pthread_create(&pthid, NULL, myfunc, NULL);
//打印父线程的id
cout << "parent thread id :" << pthread_self()<<endl;
for (int i = 0; i < 5; ++i) {
cout << "i=" << i<<endl;
}
sleep(2);
return 0;
}
parent thread id :140737354053440
i=0
i=1
i=2
i=3
i=4
Child thread id : 140737337173760
打印错误信息:
pthread_t pthid;
int ret = pthread_create(&pthid, NULL, myfunc, NULL);
if (ret != 0) {
cout << "error number: " << ret<<endl;
//打印错误信息
cout<<strerror(ret)<<endl; //#include<string.h>
}
2.单个线程退出 -- pthread_exit
表头文件 | #include <pthread.h> |
定义函数 | void pthread_exit(void *retval); |
函数说明 | pthread_exit结束调用线程的执行.所有通过pthread_cleanup_push设置的清除句柄将会被反序执行(后进先出)。 所以key值非空的线程特定数据Finalization functions被调用(参见pthread_key_create) 最后调用线程被终止。 retval是这个线程结束的返回值,可以通过在别的线程中调用pthread_join来获取这个值。(retval必须指向全局或者堆) |
返回值 | 没有返回值 |
3. 阻塞函数等待线程退出,获取线程退出状态 -- pthread_jion
表头文件 | #include <pthread.h> |
定义函数 | int pthread_join(pthread_t thread, void **retval); |
函数说明 | thread:要回收子线程的线程id retval:读出线程退出的时候携带的状态信息 用法: void* ptr; pthread_join(pthid,&ptr); ptr 指向内存和pthead_exit参数指向同一块内存地址 |
返回值 | 如果成功,返回值存储在thread_return中,并返回0,否则返回错误码: |
#include <iostream>
#include<pthread.h>
#include<unistd.h>
#include<string.h>
using namespace std;
void* myfunc(void* arg) {
//打印子线程的id
cout << "child thread id : "<< pthread_self() << endl;
for (int i = 0; i < 5; ++i) {
cout << "child i=" << i << endl;
if (i == 2) {
int *pret;
pret = new int;
*pret = 10;
//子线程退出
pthread_exit(pret);
}
}
return NULL;
}
int main(int argc,const char* argv[])
{
//创建一个子线程
//线程id变量
pthread_t pthid;
int ret = pthread_create(&pthid, NULL, myfunc, NULL);
if (ret != 0) {
cout << "error number: " << ret<<endl;
//打印错误信息
cout<<strerror(ret)<<endl;
}
//打印父线程的id
cout << "parent thread id :" << pthread_self()<<endl;
//阻塞等待子线程退出,并且回收pcb
void* ptr;
pthread_join(pthid,&ptr);
cout << "ptr = "<<*(int*)ptr << endl;
delete (int* )ptr;
for (int i = 0; i < 5; ++i) {
cout << "parent i=" << i<<endl;
}
return 0;
}
4.线程分离 -- pthread_detach
表头文件 | #include <pthread.h> |
定义函数 | int pthread_detach(pthread_t thread); |
函数说明 | 调用该函数之后不需要pthread_join 设置分离后子线程会自己回收自己的PCB |
返回值 |
5.取消线程 -- pthread_cancel
表头文件 | #include <pthread.h> |
定义函数 | int pthread_cancel(pthread_t thread); |
函数说明 | 在要杀死的子线程对应的处理的函数的内部,必须做过一次系统调用。 |
返回值 |
|
6.比较两个线程ID是否相等(预留函数)-- pthread_equal
表头文件 | #include <pthread.h> |
定义函数 | int pthread_equal(pthread_t thread_1, pthread_t thread_2); |
函数说明 | |
返回值 |
|
补充1.通过属性设置线程的分离
1)线程的属性类型:pthread_attr_t attr;
2)线程的属性操作函数:
对线程属性变化量的初始化 -- pthread_attr_init
表头文件 | #include <pthread.h> |
定义函数 | int pthread_attr_init(pthread_attr_t *attr); |
函数说明 | 对线程属性变化量的初始化 |
返回值 |
|
设置线程分离属性 -- pthread_attr_setdetachstate
表头文件 | #include <pthread.h> |
定义函数 | int pthread_attr_setdetachstate(pthread_attr_t *attr, int datachstate); |
函数说明 | 设置线程分离属性 datachstate:
|
返回值 |
|
释放线程资源函数 -- pthread_attr_destroy
表头文件 | #include <pthread.h> |
定义函数 | int pthread_attr_destroy(pthread_attr_t * attr); |
函数说明 | 释放线程资源函数 |
返回值 |
|
#include <iostream>
#include<pthread.h>
#include<unistd.h>
#include<string.h>
using namespace std;
void* myfunc(void* arg) {
//打印子线程的id
cout << "child thread id : "<< pthread_self() << endl;
return NULL;
}
int main(int argc,const char* argv[])
{
//创建一个子线程
//线程id变量
pthread_t pthid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&pthid, &attr, myfunc, NULL);
if (ret != 0) {
cout << "error number: " << ret<<endl;
//打印错误信息
cout<<strerror(ret)<<endl;
}
//打印父线程的id
cout << "parent thread id :" << pthread_self()<<endl;
for (int i = 0; i < 5; ++i) {
cout << "parent i=" << i<<endl;
}
sleep(2);
pthread_attr_destroy(&attr);
return 0;
}