linux线程的创建与删除
linux线程的创建与删除
使用linux线程时,编译时需要包含-pthread
选项。
Linux通用API返回0表示成功,返回-1表示失败,并设置errno以标识错误原因。但Pthreads相关的API却与之不同,返回0 表示成功,返回正值表示失败,正值的含义与errno相同。
我们可以使用pthread_create()
来创建线程。创建成功后的线程可以使用如下几种方式终止:
- 线程主函数中执行return语句并返回指定值。
- 调用pthread_exit()函数终止线程
- 调用pthread_cancel()取消线程。
- 任意线程调用了exit(),或者主线程执行了return语句(在main()函数中),都会导致进程中的所有线程立即终止。
当线程终止退出时,分两种情况:
- 线程为可连接(joinable)状态。这也是线程的默认状态。这种状态的线程退出时,必须使用
pthread_join()
函数连接。用于资源回收。否则会产生相当于僵尸进程的线程。除了浪费系统资源以外,僵尸线程若累积过多,应用将再也无法创建新的线程。 - 线程为分离(detached)状态。调用
pthread_detach()
将该线程标记为处于分离(detached)
状态。一旦线程被分离,就不可能再使用pthread_join()来获得它的返回状态,并且该线程也不能再次连接。这种情况一般用于程序员并不关心线程的返回状态,只是希望系统在线程终止时能够自动清理并移除之。
线程使用相关的函数API:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg)
- 创建一个线程
- thread:用于保存线程标识符的实体指针。
- attr:用于指定要创建线程的各种属性。
- start_routine:线程实体函数
- arg:线程实体函数的参数。
- return:
void pthread_exit(void *retval)
- 终止当前线程。
- retval:指定线程的返回内容。pthread_join()可获取返回的内容。retval内容不能是局部变量。必须为全局变量等。
pthread_t pthread_self(void)
- 获取当前线程的id.
int pthread_equal(pthread_t t1, pthread_t t2)
- 检查两个线程是否相等。
- return:if true:返回非0值。if false:返回0.
int pthread_join(pthread_t thread, void **retval)
- 等待某个指定的线程终止。
- thread:指定要等待终止的线程id.
- retval:用于接收线程终止后返回的内容。
- return:if true:0. if false:大于0的错误码。
- 注意:当线程终止时,必须使用pthread_join()函数连接。否则会产生相当于僵尸进程的线程。除了浪费系统资源以外,僵尸线程若累积过多,应用将再也无法创建新的线程。
- 注意:线程之间的关系是对等的。即没有进程中的父子关系等。因此进程中的任意线程均可以调用pthread_join()与该进程的任何其他线程连接起来。
int pthread_detach(pthread_t thread)
- 默认情况下,线程是可连接的(joinable),也就是说,当线程退出时,其他线程可以通过调用pthread_join()获取其返回状态。有时,程序员并不关心线程的返回状态,只是希望系统在线程终止时能够自动清理并移除之。在这种情况下,可以调用pthread_detach()并向thread 参数传入指定线程的标识符,将该线程标记为处于分离(detached)状态。一旦线程被分离,就不可能再使用pthread_join()来获得它的返回状态,并且该线程也不能再次连接。
- thread:线程id
- return:if true:0. if false:大于0的错误码。
如下是一个简单的线程创建例程:
#include <pthread.h>
#include <stdio.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>void *thread_entry(void *arg)
{int num = 0;int count = *((int *)arg);for (int i = 0; i < count; i++){num ++;}return NULL;
}void main(void)
{// 1. 定义线程描述符pthread_t t1;int counts = 20000;// 2. 创建线程if(pthread_create(&t1, NULL, thread_entry, &counts) != 0){printf("thread t1 create error.");exit(1);}// 3. 回收线程资源if(pthread_join(t1, NULL) != 0){printf("pthread_join t1 error.");exit(1);}exit(0);
}
线程取消
上面提到的线程终止函数pthread_exit()
用于自身线程的终止。但有时也需要其他线程来终止当前线程。这时就涉及到线程取消
了。
线程取消
:其他线程向本线程发送一个请求,要求本线程其立即退出。线程取消函数thread_cancel()
只负责发送一个取消请求消息,然后立即返回。至于目标线程如何处理这个请求的,取决于目标线程的取消状态state
和类型type
。
当因线程取消导致线程终止时,终止返回的内容为PTHREAD_CANCELED
.即pthread_join()中第二个参数获取到的值将是一个特殊值:PTHREAD_CANCELED
。
int pthread_cancel(pthread_t thread)
- 向目标线程发送取消请求。
- thread:目标线程id
- return:if true:0. if false:大于0的错误码。
int pthread_setcancelstate(int state, int *oldstate)
- 设置当前线程的取消状态。
- state:要设置的状态,如下:
- PTHREAD_CANCEL_DISABLE:线程不可取消。如果此类线程收到取消请求,则会将请求挂起,直至将线程的取消状态置为启用。
- PTHREAD_CANCEL_ENABLE:线程可以取消。新建线程时的默认值。
- oldstate:用于返回之前的状态。
- return:if true:0. if false:大于0的错误码。
int pthread_setcanceltype(int type, int *oldtype)
- 设置当前线程的取消类型。在取消状态设置为PTHREAD_CANCEL_ENABLE时使用。
- type:要设置的类型。
- PTHREAD_CANCEL_ASYNCHRONOUS:异步取消线程。即在线程的任何地方都可以取消。很少用。
- PTHREAD_CANCEL_DEFERED:取消请求保持挂起状态,直至到达
取消点
.新建线程时的默认值。- 什么是
取消点
:简单说就是一些系统规定的可以取消线程的函数。当满足上述条件时(即state为使能,type为挂起),遇到这些函数线程就会终止。系统规定规定的取消点函数很多,如open()
等各种系统调用。详见man手册。
- 什么是
- oldtype:用于返回之前的类型。
- return:if true:0. if false:大于0的错误码。
void pthread_testcancel(void)
- 产生一个取消点。即如果线程中没有使用系统规定取消点函数。可以使用此函数来产生取消点,而不影响程序逻辑。
在线程取消时,可能会涉及到内存释放,互斥量恢复等操作。这时会涉及到线程清理相关的函数。
void pthread_cleanup_push(void (*routine)(void*), void *arg)
- 将指定清理函数压栈。线程因取消请求进入终止状态时,会从栈顶向下依次运行栈中的清理函数。
- routine:清理函数
- arg:清理函数要传入的参数
void pthread_cleanup_pop(int execute)
- 出栈。配合pthread_cleanup_push()使用。它俩必须属于同一语法块,必须一一对应。
- execute:执行状态。
- 0:正常出栈,不执行栈顶的清理函数。
- !0,出栈时,仍然会执行栈顶的清理函数。
关于技术交流
此处后的文字已经和题目内容无关,可以不看。
qq群:825695030
微信公众号:嵌入式的日常
如果上面的文章对你有用,欢迎打赏、点赞、评论。
linux线程的创建与删除相关推荐
- Linux 线程的创建与同步
Linux 线程的创建与同步 1.线程的定义 2.线程的创建和使用 3.理解线程的并发运行 3.线程同步 3.线程的实现 1.线程的定义 线程:进程内部的一条执行路径.是资源调度和执行的基本单位. 进 ...
- linux命令 - ln - 创建和删除软、硬链接
linux命令 - ln - 创建和删除软.硬链接 在Linux系统中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号.文件属性保存在索引结点里,在访问文件 ...
- 学习Linux二(创建、删除文件和文件夹命令)
学习Linux二(创建.删除文件和文件夹命令) 今天学习了几个命令,是创建.删除文件和文件夹的,在linux里,文件夹是目录,下面说下我学习的命令. 创建文件夹[mkdir] 一.mkdir命令使用权 ...
- Linux 学习之创建、删除文件和文件夹命令
今天学习了几个命令,是创建.删除文件和文件夹的,在linux里,文件夹是目录,下面说下我学习的命令. 创建文件夹[mkdir] 一.mkdir命令使用权限 所有用户都可以在终端使用 mkdir 命令在 ...
- 浅析Linux线程的创建
本文首先使用了接口pthread_create创建一个线程,并用strace命令追踪了接口pthread_create创建线程的步骤以及涉及到的系统调用,然后讨论了Linux中线程与进程关系,最后概述 ...
- linux软链接的创建、删除和更新
大家都知道,有的时候,我们为了省下空间,都会使用链接的方式来进行引用操作.同样的,在系统级别也有.在Windows系列中,我们称其为快捷方式,在Linux中我们称其为链接(基本上都差不多了,其中可能有 ...
- linux内核系统调用创建和删除文件
一.创建文件 1.创建普通文件 int creat(const char *pathname, mode_t mode); 也可以使用open和openat创建普通文件:如果参数flags设置标志位O ...
- linux在个人目录下新建目录,Linux目录的创建与删除命令
mkdir命令 功能:创建一个目录(类似MSDOS下的md命令). 语法:mkdir [选项] dir-name 说明:该命令创建由dir-name命名的目录.要求创建目录的用户在当前目录中(dir- ...
- Linux 学习之创建,删除文件和文件夹命令
https://blog.csdn.net/linjpg/article/details/77854671
最新文章
- JavaScript 正则表达式的使用
- linux diff patch 生成和打补丁
- java求职攻略_2020年求职攻略 《Java面试连成诀》教程免费分享
- Java ServletContext 详解
- php workman 多线程,workerman如何多线程
- Ext grid js上移下移样例
- 利用微软的平台进行Office文档的在线查看
- 磁盘测试----fio
- 深度学习2.0-32.经典卷积网络VGG,GoogleNet,Inception-1
- java音频播放(转)
- 单应性(同义词直射变换、射影变换和射影性等)(来自wiki)
- java基本类型运算溢出_JAVACard 基本数据类型的运算及溢出问题
- python 读取geotiff_python gdal 写GeoTiff文件
- background背景图片铺满背景并且不重复
- 怎么使用山东鼎信发送短信验证码
- [转载]tensorflow二次开发
- 张勋说:棒磨机断棒的几个可能原因
- MSP430寄存器的设置与作用
- WOS(SCI)爬虫案例
- 平板win10 android哪个耗电,买平板电脑时,应该选win10还是安卓系统?