一、线程简介
与进程不同,线程与线程间只是栈的不同,进程则是完全复制。
二、线程id
和进程一样,每个线程也有自己的id,但线程的id仅仅只在和线程有联系的上下文中有效。
获取线程id的函数:
pthread_t pthread_self(void);
该函数返回值为调用此函数的线程id。
三、线程创建
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
参数介绍
pthread_t *thread:保存线程的相关信息,如id;
pthread_attr_t *attr:一般设置为NULL,后续详解此参数;
void *(*start_routine)(void *):此参数为要执行的函数;
void *arg:传入要执行函数的参数。
返回值
创建成功返回0,否则返回错误编号。
四、线程退出与取消
void pthread_exit(void *retval);
参数介绍
void *retval:退出状态:
调用此函数退出线程。
int pthread_cancel(pthread_t thread);
参数介绍
pthread_t thread:创建线程时的第一个参数。
返回值
成功返回0,否则返回错误编码。
注:线程退出是自己这个线程调用来退出自己的,
而线程取消则是线程来调用取消别的线程的。
int pthread_join(pthread_t thread, void **retval);
和wait函数类似,等待指定的线程运行完
void **retval获取退出状态码
线程清理处理函数
void pthread_cleanup_push(void (*routine)(void *),
void *arg);
void pthread_cleanup_pop(int execute);
参数介绍
void (*routine)(void *):执行的函数;
void *arg:传给执行函数的参数;
int execute:当该参数为0时,清理函数将不被调用。
线程执行以下动作时,清理函数被调用:
1、调用pthread_exit
2、响应线程取消
3、execute不为0
此函数与进程退出处理函数atexit相似,但该函数是记录在栈中的
所以先注册的后执行。
demo
#include <stdio.h>
#include <pthread.h>
void clean_fun(void *s)
{
printf("%s\n",(char *)s);
}
void* fun1(void *arg)
{
pthread_cleanup_push(clean_fun,"thread1 handler");
printf("thread1 is running\n");
if(arg)
{
return ((void *)1);
}
pthread_cleanup_pop(0);
return ((void *)1);
}
void* fun2(void *arg)
{
pthread_cleanup_push(clean_fun,"thread2 handler");
printf("thread2 is running\n");
if(arg)
{
pthread_exit((void *)2);
}
pthread_cleanup_pop(0);
pthread_exit(NULL);
}
int main()
{
pthread_t thread1,thread2;
int err;
void *tret;
err = pthread_create(&thread1,NULL,fun1,(void *)1);
if(err != 0)
{
printf("create thread1 failed\n");
}
err = pthread_create(&thread2,NULL,fun2,(void *)1);
if(err != 0)
{
printf("create thread2 failed\n");
}
pthread_cancel(thread2);
err = pthread_join(thread1,&tret);
if(err != 0)
{
printf("thread1 join failed\n");
}
err = pthread_join(thread2,&tret);
if(err != 0)
{
printf("thread1 join failed\n");
}
err = pthread_join(thread2,&tret);
if(err != 0)
{
printf("thread2 join failed\n");
}
printf("main thread is running\n");
return 0;
}
演示结果
pthread这个库为第三方库需要-l来链接
可以看到线程1没有满足清理函数的调用条件所以没有执行。