参考文献
Linux --线程编程
进程
- 系统中程序执行和资源分配的基本单位
- 每个进程有自己的数据段、代码段和堆栈段
- 在进行切换时需要有比较复杂的上下文切换
线程
- 减少处理机的空转时间,支持多处理器以及减少上下文切换开销, 比创建进程小很多
- 进程内独立的一条运行路线
- 处理器调度的最小单元,也称为轻量级进程
- 可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享
线程的基本使用
线程的创建
int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void *(*func)(void *), void *restrict arg);
- 第一个参数 传入一个线程结构体 线程标示符号
- 第二个参数 用来配置线程属性 基本为NULL
- 第三个参数 为回调函数
- 第四个参数 是参数
线程的结束
void
pthread_exit(void *value_ptr);
返回一个指针 相当于 return (void*)value_ptr
注意
这里不能调用exit()
否则会结束当前进程 而不是结束线程
线程的等待 类似:waitpid()
int
pthread_join(pthread_t thread, void **value_ptr);
- thread 需要等待的线程
- value_ptr 线程的返回参数
代码
#include
#include
#include
void *thrd_func1(void *arg);
void *thrd_func2(void *arg);
int main(){
pthread_t tid1,tid2;
void *tret;
// 创建线程tid1,线程函数thrd_func1
if (pthread_create(&tid1,NULL,thrd_func1,NULL)!=0) {
printf("Create thread 1 error!\n");
exit(1);
}
// 创建线程tid2,线程函数thrd_func2
if (pthread_create(&tid2,NULL,thrd_func2,NULL)!=0) {
printf("Create thread 2 error!\n");
exit(1);
}
void *tret;
// 等待线程tid1结束,线程函数返回值放在tret中
if (pthread_join(tid1,&tret)!=0){
printf("Join thread 1 error!\n");
exit(1);
}
printf("Thread 1 exit code: %d.\n",(int *)tret);
// 等待tid2结束,线程函数返回值放在tret中
if (pthread_join(tid2,&tret)!=0){
printf("Join thread 2 error!\n");
exit(1);
}
printf("Thread 2 exit code: %d.\n",(int *)tret);
return 0;
}
void *thrd_func1(void *arg){
printf("Thread 1 exiting!\n");
// sleep(3);
return ((void *)1); // 自动退出线程
}
void *thrd_func2(void *arg){
printf("Thread 2 exiting!\n");
pthread_exit((void *)2); // 线程主动退出,返回(void *)2
}
线程取消
参考文献
int
pthread_cancel(pthread_t thread);
#include
int
pthread_setcancelstate(int state, int *oldstate);
int
pthread_setcanceltype(int type, int *oldtype);
void
pthread_testcancel(void);
pthread_setcancelstate() 函数用来设置当前线程的“可取消性”状态,并且将先前的状态返回到oldstate引用中。“可取消性”状态的合法值分别是:PTHREAD_CANCEL_ENABLE 和 PTHREAD_CANCEL_DISABLE.这个函数还可以查询当前线程的“可取消性”状态,即把第一个参数设为NULL。
pthread_setcanceltype() 函数用来设置当前线程的“可取消类型”,并且将先前的类型返回到oldtype引用中。
“可取消类型”的合法值分别是:
- PTHREAD_CANCEL_DEFERRED :线程接收到取消操作后,直到运行到“可取消点”后取消。
- PTHREAD_CANCEL_ASYNCHRONOUS :线程接收到取消操作后,立即取消。
“可取消性”和“可取消类型”存在于任意一个新建线程中,包括主线程
默认设置是
- PTHREAD_CANCEL_ENABLE
- PTHREAD_CANCEL_DEFERRED。
pthread_testcancel()函数用来在当前线程创建一个“可取消点”。如果当前线程是不能取消的,则这个函数无效
#include
#include
#include
void *thrd_func1(void *arg);
void *thrd_func2(void *arg);
pthread_t tid1,tid2;
int main(){
// 创建线程tid1,线程函数thrd_func1
if (pthread_create(&tid1,NULL,thrd_func1,NULL)!=0) {
printf("Create thread 1 error!\n");
exit(1);
}
// 创建线程tid2,线程函数thrd_func2
if (pthread_create(&tid2,NULL,thrd_func2,NULL)!=0) {
printf("Create thread 2 error!\n");
exit(1);
}
// 等待线程tid1退出
if (pthread_join(tid1,NULL)!=0){
printf("Join thread 1 error!\n");
exit(1);
}else
printf("Thread 1 Joined!\n");
// 等待线程tid2退出
if (pthread_join(tid2,NULL)!=0){
printf("Join thread 2 error!\n");
exit(1);
}else
printf("Thread 2 Joined!\n");
return 0;
}
void *thrd_func1(void *arg){
// pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); // 设置其他线程可以cancel掉此线程
while(1) {
printf("Thread 1 is running!\n");
sleep(1);
}
pthread_exit((void *)0);
}
void *thrd_func2(void *arg){
printf("Thread 2 is running!\n");
sleep(5);
if (pthread_cancel(tid1)==0) // 线程tid2向线程tid1发送cancel
printf("Send Cancel cmd to Thread 1.\n");
pthread_exit((void *)0);
}