当前位置:   article > 正文

Linux多线程编程常用接口函数_einval pthread

einval pthread

目录

1.线程介绍

2.线程函数

1)pthread_create()

2)pthread_self()

3)pthread_exit()

4)pthread_cancel()

5)pthread_join()

6)pthread_detach()

1.线程介绍

一个进程可以包含多个线程,这些线程共享相同的代码(即应用程序的代码)、数据(包括全局变量、函数内的静态变量、堆空间的数据等)、进程空间(操作系统分配给进程的内存空间)、文件描述符(各个线程打开的文件资源,也可以为所有线程所共享),但每个线程都有自己的堆栈。

线程共享的属性(这些属性是进程范围而不是每个线程):

  • 进程ID
  • 父进程ID
  • 进程组ID和会话ID
  • 控制终端
  • 用户id和组id
  • 打开的文件描述符
  • 记录锁
  • 信号处理
  • 文件权限掩码
  • 当前目录和根目录
  • 间隔计时器和POSIX定时器
  • nice值
  • 资源限制
  • CPU时间和资源消耗的度量

线程独有的属性:

  • 堆栈
  • 线程ID
  • 信号掩码
  • errno变量
  • 备用信号栈
  • 实时调度策略和优先级

  • CPU亲和力/亲缘性

2.线程函数

1)pthread_create()

pthread_create()用来创建一个新的线程,其语法格式如下: 

各个参数的含义是:

  • thread:表示pthread_create函数调用成功后,新建线程的线程ID。
  • attr:指定新线程的属性。当attr设置为 NULL,表示新建线程遵循默认属性((非绑定、非分离、默认堆栈大小及与父进程同样级别的优先级)。
  • start_routine:以函数指针的方式指明新建线程需要执行哪个函数。
  • arg:向 start_routinue() 函数的形参传递数据。将 arg 置为 NULL,表示不传递任何数据。

linux线程的终止的几种方式:

  • 调用pthread_exit(),指定退出状态值,该值可用于调用pthread_join()的同一进程中的另一个线程。
  • 函数start_routine()使用return返回。这相当于调用pthread_exit()。
  • 线程被取消(其他线程调用pthread_cancel()函数)。
  • 进程中的任何线程都调用exit(),或者主线程从main()执行返回。这会导致进程中所有线程的终止。

pthread_create如果调用成功,则返回0,如果失败则返回一个错误码,并且参数thread的值未定义。

2)pthread_self()

pthread_self()用于获取调用线程的线程ID,其语法格式如下:

这个函数 调用总是成功,返回值为调用线程的线程ID。

3)pthread_exit()

pthread_exit()用于结束调用线程,其语法格式如下:

pthread_exit()函数终止调用线程并通过retval返回一个值(如果线程是非分离的),该值可用于调用pthread_join()的同一进程中的另一个线程。 

当线程终止时,进程共享资源(例如互斥锁、条件变量、信号量和文件描述符)不会被释放,使用atexit()注册的函数也不会被调用。

在进程中的最后一个线程终止后,该进程通过调用exit()终止,退出状态为0;因此,进程共享资源被释放,使用atexit()注册的函数被调用。

注意,retval 不能指向函数内部的局部变量,否则会导致程序运行出错甚至崩溃。

4)pthread_cancel()

pthread_cancel()用于向另一个线程发送取消请求,其语法格式如下:

pthread_cancel()函数向线程thread发送一个取消请求。目标线程是否以及何时对取消请求做出反应取决于该线程控制下的两个属性:其可取消性状态和类型。

线程的可取消状态由pthread_setcancelstate()决定,可以enable(新线程的默认值)或disable。如果线程已禁用取消,则取消请求将保持在队列中,直到该线程启用取消。如果线程启用了取消,那么它的可取消性类型确定取消发生的时间。

 线程的取消类型由pthread_setcanceltype()决定,可以是异步的,也可以是延迟的(新线程的默认值)。异步可取消性意味着线程可以在任何时候被取消(通常是立即取消,但系统不保证这一点)。延迟取消性意味着取消将被延迟,直到线程下一次调用取消点的函数。

pthread_cancle执行成功则返回0,失败则返回非零错误码。

5)pthread_join()

pthead_join()用于等待另一个线程结束。其语法格式如下:

 pthread_join()函数等待thread指定的线程终止。如果该线程已经终止,那么pthread_join()立即返回。由thread指定的线程必须是可连接(即非分离)的。

如果retval不为NULL,那么pthread_join()将目标线程的退出状态(即,目标线程提供给pthread_exit()的值)复制到retval指向的位置。如果目标线程被取消了,那么将PTHREAD_CANCELED放置在retval指向的位置。

如果多个线程同时尝试与同一个线程进行连接,结果是未定义的。如果调用pthread_join()的线程被取消,那么目标线程将保持可连接状态(即不会被分离)。

成功时,pthread_join()返回0;如果发生错误,则返回错误码。常见的错误如下:

EDEADLK —— 检测到死锁(例如,两个线程试图相互连接);或参数thread指定调用线程。

EINVAL—— 线程不是一个可连接线程。

EINVAL—— 另一个线程已经在等待连接这个线程。

ESRCH —— 没有找到ID为thread的线程。

注意:

  • 在成功调用pthread_join()之后,调用者可以保证目标线程已经终止。然后,调用者可以选择在线程终止后进行任何需要的清理(例如,释放分配给目标线程的内存或其他资源)。
  • 连接之前已经连接过的线程会导致未定义的行为。
  • 与可连接的线程(即未分离的线程)连接失败,将产生“僵尸线程”。要避免这样做,因为每个僵尸线程都会消耗一些系统资源,当积累了足够多的僵尸线程时,就不可能再创建新线程(或进程)。
  • 进程中的所有线程都是对等的:进程中的任何线程都可以与其他线程连接。

6)pthread_detach()

pthread_detach()用来分离一个线程。其语法格式如下:

pthread_detach()函数将thread标识的线程标记为已分离。当分离的线程终止时,其资源将自动释放回系统,而不需要另一个线程与终止的线程连接。

试图分离已经分离的线程会导致未指定的行为。

 成功时,pthread_detach()返回0;如果发生错误,则返回错误码。

参考资料:

1.Linux多线程编程(10分钟入门)

2.Linux manual pages: section 3


   

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/936449
推荐阅读
相关标签
  

闽ICP备14008679号