Linux 进程与线程二(等待--分离--取消线程)
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 = ;
return p;
} void * Myfunc2(void *arg)
{
int *p = (int *) malloc(sizeof(int));
if (p == NULL)
{
printf("分配内存失败!\n");
return NULL;
}
*p = ;
pthread_exit(p);
} int main(int arg, char *args[])
{
pthread_t thr1, thr2;
if (pthread_create(&thr1, NULL, Myfunc, NULL) != )
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -;
}
if (pthread_create(&thr2, NULL, Myfunc2, NULL) != )
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -;
}
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 ;
}
int pthread_detach(pthread_t th);
pthread_detach函数使线程处于被分离状态。
对于被分离状态的线程,同时对线程的返回值不感兴趣,可以设置这个线程被分离状态,让系统在线程退出的时候自动回收它所占用的资源。
一个线程不能自己调用pthread_detach改变自己被分离状态,只能由其他线程调用pthread_detach。
一旦线程成为可分离线程之后,就不能再使用pthread_joisn()函数了,因为没有意义。
pthread_detach()成功返回0,失败返回错误码。
线程处于被分离状态下,控制线程退出,被分离线程也会退出,被分离线程只是不需要使用pthread_join函数来释放内存资源。 可分离线程的使用场景
.主线程不需要等待子线程
.主线程不关心子线程的返回码
//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()
{
printf("fly with me \n");
sleep();
}
return NULL;
} int main(int arg, char *args[])
{
pthread_t thr1;
if (pthread_create(&thr1, NULL, Myfunc, NULL) != )
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -;
}
pthread_detach(thr1);
sleep();
printf("main end \n");
return ;
}
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 ()
{
printf("fly with me \n");
sleep();
}
int *p = malloc(sizeof(int));
*p = ;
return p;
} void * Myfunc2(void *arg)
{
if(arg==NULL)
{
printf("param is not allow NULL!\n");
return NULL;
}
sleep();
pthread_t thr;
thr=*(pthread_t *)arg;
pthread_cancel(thr);
int *p = malloc(sizeof(int));
*p = ;
return p;
} int main(int arg, char *args[])
{
pthread_t thr1, thr2;
if (pthread_create(&thr1, NULL, Myfunc, NULL) != )
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -;
}
if (pthread_create(&thr2, NULL, Myfunc2, &thr1) != )
{
printf("create thread is failed ! error message :%s\n",
strerror(errno));
return -;
}
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 ;
}
Linux 进程与线程二(等待--分离--取消线程)的更多相关文章
- linux进程管理(二)
接上[linux进程管理(一)] 终止进程的工具 kill .killall.pkill 终止一个进程或终止一个正在运行的程序,一般是通过 kill .killall.pkill.xkill 等进行. ...
- Linux进程控制(二)
1. 进程的创建 Linux下有四类创建子进程的函数:system(),fork(),exec*(),popen() 1.1. system函数 原型: #include <stdlib.h&g ...
- Linux进程管理(二、 进程创建)
通常使用fork创建进程, 也可以用vfork()和clone().fork.vfork和clone三个用户态函数均由libc库提供,它们分别会调用Linux内核提供的同名系统调用fork,vfork ...
- [Java][Android] 多线程同步-主线程等待全部子线程完毕案例
有时候我们会遇到这种问题:做一个大的事情能够被分解为做一系列相似的小的事情,而小的事情无非就是參数上有可能不同样而已! 此时,假设不使用线程,我们势必会浪费许多的时间来完毕整个大的事情.而使用线程的话 ...
- 从源码解读线程(Thread)和线程池(ThreadPoolExecutor)的状态
线程是比进程更加轻量级的调度执行单位,理解线程是理解并发编程的不可或缺的一部分:而生产过程中不可能永远使用裸线程,需要线程池技术,线程池是管理和调度线程的资源池.因为前不久遇到了一个关于线程状态的问题 ...
- Java 之 线程的生命周期(线程状态)
一.线程的生命周期 (1)新建状态 new 好了一个线程对象,此时和普通的 Java对象并没有区别. (2)就绪 就绪状态的线程是具备被CPU调用的能力和状态,也只有这个状态的线程才能被CPU调用.即 ...
- Linux进程与线程的区别
进程与线程的区别,早已经成为了经典问题.自线程概念诞生起,关于这个问题的讨论就没有停止过.无论是初级程序员,还是资深专家,都应该考虑过这个问题,只是层次角度不同罢了.一般程序员而言,搞清楚二者的概念, ...
- Py修行路 python基础 (二十五)线程与进程
操作系统是用户和硬件沟通的桥梁 操作系统,位于底层硬件与应用软件之间的一层 工作方式:向下管理硬件,向上提供接口 操作系统进行切换操作: 把CPU的使用权切换给不同的进程. 1.出现IO操作 2.固定 ...
- Linux 系统编程 学习:09-线程:线程的创建、回收与取消
Linux 系统编程 学习:09-线程:线程的创建.回收与取消 背景 我们在此之前完成了 有关进程的学习.从这一讲开始我们学习线程. 完全的开发可以参考:<多线程编程指南> 在Linux ...
随机推荐
- Android实战--电话拨号器
今天跟着黑马视频建立一个android app--电话拨号器 首先新建一个android项目 activity_main_xml中的代码如下: <RelativeLayout xmlns:and ...
- 关于android4.3 Intel X86 Atom System Image的下载
今天建立android4.3模拟器的时候发现没有android4.3 Intel X86 Atom System Image可选,打开android SDK Manager 于是希望重现选择下载安装, ...
- 初识 Android
创建博客有一年的时间了,一直没把它用起来,颇感惭愧.近日突感有写博客的冲动,更可怕的是这种冲动似乎比我体内的洪荒之力更为凶猛.于是乎,这篇博客悄然诞生.废话不多说,进入正题--初识Android. 这 ...
- 【读书笔记】iOS-简单的数据驱动程序
一,效果图. 二,,工程文件如下图所示: 三,DataModel.h #import <Foundation/Foundation.h> @interface DataModel : ...
- Struts2(十二)使用验证框架验证数据较验
一.数据验证 1.1.为什么要进行数据验证 对数据的合法性进行检查,只允许合法的数据进入应用程序 1.2.在哪里实现数据验证 客户端验证: 数据提交前在客户端验证 可使用JavaScript或者JQu ...
- Silverlight项目笔记5:Oracle归档模式引起的异常&&表格控件绑定按钮
1.Oracle归档模式产生日志文件引起数据库异常 连接数据库失败,提示监听错误,各种检查监听配置文件,删除再添加监听,无果. sqlplus下重启数据库数据库依然无果,期间碰到多个错误提示: ORA ...
- Xcode的内存清理
1.删除Xcode中多余的证书provisioning profile 手动删除: 打开finder,然后在最上面的前往中前往下方的路径,就可以看到你xcode运行到现在使用过的证书provision ...
- eclipse执行单元测试报CreateProcess error=87的解决方法
原因是classpath的路径过长导致,在网上看了很多文章,发现解决方法有2种: 1.更改项目路径 或者 maven本地库的路径,减少classpath的深度. 2.由于这是eclipse自身的bug ...
- 深入理解CSS中的层叠上下文和层叠顺序
零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在C ...
- Stack与Heap的区别
申明:这里所说的栈和堆是程序内存管理中的栈和堆,而不是数据结构里的栈和堆. (1)保存的内容不同:栈里保存的是局部变量,而堆里保存的是动态申请的变量. (2)栈里的内存系统自动申请和释放,程序执行出申 ...