您的位置:首页 > 运维架构 > Linux

Linux 进程与线程二(等待--分离--取消线程)

2016-09-10 22:40 459 查看
int pthread_join(pthread_t thr,void **thr_return);
pthread_join函数用于挂起当前线程,直至th指定的线程终止为止。
如果另一个线程返回值不是NULL,则保存在thr_return地址中。
一个线程所使用的内存资源在应用pthread_join调用之前不会被重新分配,所以对于每个线程必须调用一次pthread_join函数(被分离线程除外)。
其他线程不能对同一线程再应用pthread_join调用。
pthread_join函数成功返回0,失败返回错误码
参数thr_return就是线程th的返回值
这个函数的应用场景一般是在控制线程中调用,用来等待其他线程返回,跟进程中wait()函数类似。
一个线程退出后(在控制线程不退出的情况下),该线程所使用的内存资源并没有被释放,需要调用pthread_join()函数释放。


//pthread_join的使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <errno.h>
#include <pthread.h>

void * Myfunc(void *arg)
{
int *p = (int *) malloc(sizeof(int));
if (p == NULL)
{
printf("分配内存失败!\n");
return NULL;
}
*p = 5;
return p;
}

void * Myfunc2(void *arg)
{
int *p = (int *) malloc(sizeof(int));
if (p == NULL)
{
printf("分配内存失败!\n");
return NULL;
}
*p = 10;
pthread_exit(p);
}

int main(int arg, char *args[])
{
pthread_t thr1, thr2;
if (pthread_create(&thr1, NULL, Myfunc, NULL) != 0)
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -1;
}
if (pthread_create(&thr2, NULL, Myfunc2, NULL) != 0)
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -1;
}
int *returnnum1 = NULL;
int *returnnum2 = NULL;
/*
pthread_join()函数主要的量大的功能
1.将控制线程挂起,等待指定的线程返回
2.释放指定的线程的内存资源(线程正常退出并没有释放自身占用的资源,除非进程退出)
*/
pthread_join(thr1, (void **) &returnnum1);
if (returnnum1 != NULL)
{
printf("thr1 return number is %d\n", *returnnum1);
}

pthread_join(thr2, (void **) &returnnum2);
if (returnnum2 != NULL)
{
printf("thr2 return number is %d\n", *returnnum2);
}
return 0;
}


int pthread_detach(pthread_t th);
pthread_detach函数使线程处于被分离状态。
对于被分离状态的线程,同时对线程的返回值不感兴趣,可以设置这个线程被分离状态,让系统在线程退出的时候自动回收它所占用的资源。
一个线程不能自己调用pthread_detach改变自己被分离状态,只能由其他线程调用pthread_detach。
一旦线程成为可分离线程之后,就不能再使用pthread_joisn()函数了,因为没有意义。
pthread_detach()成功返回0,失败返回错误码。
线程处于被分离状态下,控制线程退出,被分离线程也会退出,被分离线程只是不需要使用pthread_join函数来释放内存资源。

可分离线程的使用场景
1.主线程不需要等待子线程
2.主线程不关心子线程的返回码


//pthread_detach的使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <errno.h>
#include <pthread.h>

void * Myfunc(void *arg)
{
while(1)
{
printf("fly with me \n");
sleep(1);
}
return NULL;
}

int main(int arg, char *args[])
{
pthread_t thr1;
if (pthread_create(&thr1, NULL, Myfunc, NULL) != 0)
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -1;
}
pthread_detach(thr1);
sleep(3);
printf("main end \n");
return 0;
}


int pthread_cancel(pthread_t th);
pthread_cancel函数允许一个线程取消th指定的另一个线程
函数成功返回0,失败返回非0.


//pthread_join的使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <errno.h>
#include <pthread.h>

void * Myfunc(void *arg)
{
while (1)
{
printf("fly with me \n");
sleep(1);
}
int *p = malloc(sizeof(int));
*p = 7;
return p;
}

void * Myfunc2(void *arg)
{
if(arg==NULL)
{
printf("param is not allow NULL!\n");
return NULL;
}
sleep(5);
pthread_t thr;
thr=*(pthread_t *)arg;
pthread_cancel(thr);
int *p = malloc(sizeof(int));
*p = 8;
return p;
}

int main(int arg, char *args[])
{
pthread_t thr1, thr2;
if (pthread_create(&thr1, NULL, Myfunc, NULL) != 0)
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -1;
}
if (pthread_create(&thr2, NULL, Myfunc2, &thr1) != 0)
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -1;
}
int *numx1 = NULL;
int *numx2 = NULL;
pthread_join(thr1, (void **) &numx1);
pthread_join(thr2, (void **) &numx2);
/*
程序报错,线程thr1在执行中被强制取消,返回值numx1并不是NULL
*/
/*
if (numx1 != NULL)
{
printf("thr1 return code is %d\n", *numx1);
free(numx1);
numx1 = NULL;
}
*/
if (numx2 != NULL)
{
printf("thr2 return code is %d\n", *numx2);
free(numx2);
numx2 = NULL;
}
printf("main end \n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: