POSIX 线程的创建与退出

创建线程:

退出线程:

使用多线程,首先就需要创建一个新线程。那么线程是如何被创建的呢,是用下面这个函数创建的。

创建函数的四个参数的意义分别如下:

返回值:如果函数执行成功,则返回 0,如果执行失败,则返回一个错误码。

错误码:

下面就是调用 pthread_create() 函数创建线程的一个例子:

接下来编译并运行,看看结果:

看起来执行成功了。下面再来看看一个线程的退出过程。

从上面的例子中,我们也可以看出,线程的入口,也就是一个函数,函数可以使用 return 进行退出, 那么在线程中,也是通过 return 进行退出的吗? 答案是,可以使用 return ,但是如果希望线程在退出的时候, 能够执行更多的动作,就不能使用 return 直接退出了,那么该怎样退出呢,可以使用 pthread_exit() 函数, 或者使用pthread_cancel() 函数。

这两个函数的原型如下:

使用 pthread_exit() 退出线程

pthread_exit() 函数会结束当前进程。如果当前线程是可以被 join 的,则会通过参数 retval 返回一个值给同一个进程里面的另一个使用pthread_join(3) 函数的线程。

所有使用pthread_cleanup_push(3)函数压入栈的清理函数,都会被弹出并调用, 调用顺序是入栈时的反向顺序。如果线程有什么特别指定的数据,那么在所有的清理函数执行结束后, 会有适当的函数被调用,来析构这些数据,调用顺序不固定。

当一个线程终止后,进程内共享的资源(例如互斥信号量、条件变量、信号量以及文件描述符) 不会被释放。并且使用atexit(3)函数注册的函数也不会被调用。

当进程内的最后一个线程终止后,进程也就终止了,就像调用了exit(3)函数一样,并且参数是0. 这时候,进程内的共享资源就会被释放,并且使用 atexit(3) 函数注册的函数, 也会被调用。

下面来看一下 pthread_exit() 函数的一个例子:

编译并运行:

使用 return 退出线程

先来看一个使用 return 退出线程的例子:

编译并运行:

既然 return 和 pthread_exit() 函数都是结束线程,并返回数据,那么它们之间的区别是什么呢?

编译并运行:

可以看出,确实没有执行清理函数,为什么呢?

因为pthread_cleanup_push(3) 和 pthread_cleanup_pop() 是使用宏实现的。 在 pthread_cleanup_push() 和 pthread_cleanup_pop() 之间,是一个大个的 do{}while(0), 遇到 return 当然就直接退出啦。 具体的实现方式请看这里, 因为本文只讲述一下线程的创建和退出, 所以 pthread_cleanup_push 和 pthread_cleanup_pop 的说明放在其它地方了。

使用 pthread_cancel() 退出线程

先看一下函数原型:

其中的 thread 参数就是目的线程的线程ID

pthread_cancel() 函数会给 thread 指定的线程发送一个取消请求。 至于目标线程是否以及合适对这个请求进行反应,则视目标线程的两个属性而定: 取消属性的 state 和 type

一个线程的取消属性的 state 由 pthread_setcancelstate(3) 函数来设置, 可以是 enabled (一个新创建的线程的默认方式就是 enabled)或者 disabled。 如果一个线程的取消属性设置了 disabled ,那么对着个线程发送的取消请求会一直存在, 直到线程恢复了取消属性的设置。如果一个线程的取消属性设置了 enabled , 那么取消属性的 type 就由取消消息什么什么时候到来而决定了。

一个线程的取消类型(type)由 pthread_setcanceltype(3) 函数来设置。 可以是异步的,也可以是延缓的。异步取消属性的意味着线程任何时间都可以被取消 (通常是立即被取消,但操作系统不保证这一点)。延缓取消是说,取消操作会被延迟, 直到线程接下来的调用的函数是个取消点。在 pthreads(7) (Linux 命令行中执行 man 7 pthreads) 中列出的函数就是或者是取消点。

当一个取消请求起作用时,下面的步骤会按顺序发生。

*
1. 取消清理函数会被出栈并被执行。
*
1. 线程相关数据会被析构,顺序不确定。
*
1. 线程终止。

以上的步骤会异步的执行,pthread_cancel() 函数的返回状态会指出取消请求是否成功的发给了制定的线程。

在一个被取消的线程终止后,使用 pthread_join(3) 函数 join 时,会得到线程的结束状态为 PTHREAD_CANCELED 。 join 一个线程是知道这个取消操作是否完成的唯一方法。

下面是 man pthread_cancel 手册中的一段示例代码:

编译并运行 :

Original: https://www.cnblogs.com/fengbohello/p/7583630.html
Author: fengbohello
Title: POSIX 线程的创建与退出

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/540155/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 重启rabbitmq服务

    重启rabbitmq服务通过两个命令来实现: rabbitmqctl stop :停止rabbitmq rabbitmq-server restart : 重启rabbitmq 因…

    Java 2023年5月30日
    0128
  • 接口

    基本介绍:接口就是给出一些没有实现的方法,封装到以一起,到某个类要使用的时候再根据具体情况把 这些方法写出来。 语法: interface 接口名 { //属性 //方法(1.抽象…

    Java 2023年6月5日
    078
  • Java正则表达式使用 | 叠加

    public class Test { public static void main(String[] args) { String s = "ni\nhao\nma …

    Java 2023年5月29日
    068
  • 【Java】命令

    jar 一. 参数类型说明 1. 标准参数(-) 2. 非标准参数(-X) 3. 非Stable参数(-XX) 4. 程序参数(–) 5. 环境变量(-D) 二. 使用…

    Java 2023年5月29日
    077
  • 【AS3代码】擦窗户效果(也就是流行的妄撮游戏)

    源码下载:《 妄撮 (Mosatsu)》撕掉她的衣服在线 游戏 package{import flash.display.Bitmap;import flash.display.L…

    Java 2023年5月29日
    0116
  • Java 访问修饰符

    访问修饰符 访问修饰符是用于控制 类、成员方法、属性 的被访问权限。 Java为我们提供了四种服务修饰符,分别是 public、 protected、 default、 priva…

    Java 2023年6月5日
    089
  • SpringMvc 如何同时支持 Jsp 和 Json 接口?

    后端同学基本都会见过这种场景:在同一个工程中,有些页面使用jsp模版渲染,同时还有其他接口提供Json格式的返回值。为了同时支持这两种场景,我们一般是如何处理的呢? 其实非常简单:…

    Java 2023年6月16日
    055
  • 你文件乱码了么

    之前对文件的编码,解码一直停留在很抽象的层面,就想着各种编码方式,什么gbk,utf8,ascii等等,然后什么方式编码,就用什么方式解码,比较模糊的,而且项目中uft8编码无处不…

    Java 2023年6月6日
    095
  • 洛谷P3366 【模板】最小生成树(Boruvka算法)

    题意 题目链接 Sol 自己yy着写了一下Boruvka算法。 算法思想很简单,就是每次贪心的用两个联通块之间最小的边去合并。 复杂度(O(n \log n)),然鹅没有Krusk…

    Java 2023年5月30日
    095
  • Java中你所不知道的null

    先看一个示例,读者可先自行阅读判断输出结果: 上述事例会正确输出:testMethod 分析:首先应该明白的是此处是针对类对方法的调用,而不是对象对方法的调用; 其次,testMe…

    Java 2023年5月29日
    074
  • Cron表达式(七子表达式)

    秒 分 时 日 月 周 年 可用的值 0~59 0~59 0~23 1~31 1~12(JAN-DEC) 1~7(SUN-SAT) 1970~2099 可用的通配符 , &#821…

    Java 2023年6月8日
    059
  • Spring Tool Suite 4 Install Wizard Template (To Support Dynamic Web Project )

    Latest Eclipse Release – https://download.eclipse.org/releases/latest Web, XML, Java…

    Java 2023年5月30日
    068
  • Spring官网下载dist.zip的几种方法

    Spring官网改版后,很多项目的完整zip包下载链接已经隐掉了,虽然Spring旨在引导大家用更”高大上”的maven方式来管理所依赖的jar包,但是完全…

    Java 2023年5月30日
    067
  • 6. 软件架构的演进过程

    1.软件架构的演进过程 1.1单一应用架构(ORM) 当网站流量&am…

    Java 2023年6月5日
    078
  • Java集合原理分析和知识点大杂烩(多图初学者必备!!)

    一、数据结构 ​ 数据结构就是计算机存储、组织数据的方式。 ​ 在计算机科学中,算法的时间复杂度是一个函数,它定性描述了该算法的运行时间,常用O符号来表述。​ 时间复杂度是同一问题…

    Java 2023年6月7日
    073
  • 密集计算场景下的 JNI 实战

    作者:vivo 互联网服务器团队- Wei Qianzi、Li Haoxuan 在 Java 发展历程中,JNI 一直都是一个不可或缺的角色,但是在实际的项目开发中,JNI 这项技…

    Java 2023年6月15日
    064
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球