目录
线程是最小的执行单位,进程是最小的系统资源分配单位
创建一个线程
- int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
- thread 线程的id,传出参数
- attr 代表线程的属性
- 第三个参数 函数指针,void * func(void*)
- arg 线程执行函数的参数
- 返回值
- 成功返回 0
- 失败返回errno
- 编译的时候需要加 pthread库(使用所有线程库都需要加):"Compile and link with -pthread"
下面举出一个创建线程的例子:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void* thr(void *arg)
{
printf("I am a thread!pid =%d,tid=%lu\n",getpid(),pthread_self());
return NULL;
}
int main()
{
pthread_t tid;
pthread_create(&tid,NULL,thr,NULL);
printf("I am a main thread,pid = %d,tid=%lu\n",getpid(),pthread_self());
// sleep(1);
return 0;
}
执行的时候应该输入的命令为:
后面须加"-lpthread" 。运行后结果为:
线程的退出
pthread_exit
线程退出注意事项:
- 在线程中使用pthread_exit
- 在线程中使用return (主控线程return 代表退出进程)
- exit 代表退出整个进程
这两个使用效果一样:
//return NULL;
pthread_exit(NULL);
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
void *thr(void *arg)
{
printf("I am a thread,pid=%d,tid=%lu\n",getpid(),pthread_self());
//return NULL;
pthread_exit(NULL);
exit(1);
}
int main()
{
pthread_t tid;
pthread_create(&tid,NULL,thr,NULL);
printf("I am main thread,pid=%d,tid=%lu\n",getpid(),pthread_self());
sleep(10);
printf("I will out\n");
pthread_exit(NULL);
return 0;
}
运行如下:
线程的回收
可以回想一下进程,当进程死之后,如果没有回收资源,那么其父进程会变成僵尸进程。同理,当线程死之后,如果其父线程没有将其回收,也会导致僵尸线程。所以,线程也是需要回收的。
阻塞等待回收函数
int pthread_join(pthread_t thread, void **retval);
- thread 创建的时候传出的第一个参数
- retval代表的传出线程的退出信息
示例代码如下:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void * thr(void *arg)
{
printf("I am a thread,tid=%lu\n",pthread_self());
sleep(5);
printf("I am a thread,tid=%lu\n",pthread_self());
return (void*)100;
}
int main()
{
pthread_t tid ;
pthread_create(&tid,NULL,thr,NULL);
void *ret;
pthread_join(tid,&ret);//线程回收
printf("ret exit with %d\n",(int)ret);
pthread_exit(NULL);
}
运行如下:
杀死一个进程
int pthread_cancel(pthread_t thread);
- 需要出入tid
- 返回值:失败返回 errno;成功返回 0
如果一个线程是被pthread_cancel杀死的,退出状态为PTHREAD_CANCELED
#define PTHREAD_CANCELED ((void *) -1)
举例:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *thr(void *arg)
{
while(1){
//while体内必须有代码,起到取消点的作用,要不然杀不掉线程
printf("I am a thread,very happy!tid = %lu\n",pthread_self());
sleep(1);
}
return NULL;
}
int main()
{
pthread_t tid;
pthread_create(&tid,NULL,thr,NULL);
sleep(5);
pthread_cancel(tid);//杀死线程
void *ret;
pthread_join(tid,&ret);
printf("thread exit with %d\n",(int)ret);
return 0;
}
这个函数很简单,就传一个tid就可以了,这样就可以杀死这个线程了(让线程停止运行),需要提示是,while体内必须有代码,起到取消点的作用,要不然杀不掉线程。
线程分离
起到的作用是,如果这个函数被设置了,那线程回收,就不需要管了,系统就自己回收了,即不需要pthread_join回收资源。
int pthread_detach(pthread_t thread);
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
void *thr(void *arg)
{
printf("I am a thread,self = %lu\n",pthread_self());
sleep(4);
printf("I am a thread,self = %lu\n",pthread_self());
return NULL;
}
int main()
{
pthread_t tid;
pthread_create(&tid,NULL,thr,NULL);
pthread_detach(tid);//线程分离
sleep(5);
int ret = 0;
if((ret=pthread_join(tid,NULL)) > 0 ){
printf("join err:%d,%s\n",ret,strerror(ret));
}
return 0;
}
运行如下:
会发现设置了线程分离之后,再去进行线程回收,就会报错,可见线程分离实现了线程回收的功能。