https://blog.csdn.net/weixin_38102771/article/details/91351126
https://blog.csdn.net/qq_29677867/article/details/108571388?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-0&spm=1001.2101.3001.4242
一.什么是线程
你可以想象你一边听歌一边打游戏,如果是操作系统会怎么做呢?先执行 ListenMusic 再执行 PlayGame,还是先执行 PlayGame 再执行 ListenMusic 呢?好像都不太合适。为了实现这个目的,就需要引入线程这个概念。线程是 CPU 调度的最小执行单位,你可以创建一个线程用于 ListenMusic,再创建一个线程去 PlayGame,这样操作系统就是同时处理这两个任务的(并发)。

二.pthread库
(1) 使用说明
POSIX 标准定义了一套线程操作相关的函数,用于让程序员更加方便地操作管理线程,函数名都是以前缀 pthread_ 开始,使用时要包含 <pthread.h>,而且在链接的时候要手动链接 pthread 这个库,如:gcc main.c -lpthread -o main。

(2) 常用函数

  1. pthread_create
    函数原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

功能说明:创建一个线程。

参数说明

thread:线程句柄,需要先定义一个 pthread_t 类型变量 thread,将该变量的地址 &thread 传递到该参数中去。这是一个传出参数,传递进去的 thread 会得到系统为我们创建好的线程句柄。

attr:线程属性,通过该参数可以设置创建的线程属性,如果要使用默认属性直接传递 NULL 即可。

start_routine:线程函数,它是一个函数指针类型,返回类型为 void *,参数为一个 void * 类型变量,创建好这样类型的一个函数,将函数名传递进去即可。

arg:线程参数,代表需要在主线程传递给子线程的参数,给 arg 赋值后可以在线程函数的参数中取到。

返回值说明

    成功情况下返回 0,失败情况下返回错误码,并且 tid 的值是不确定的。Linux 环境下所有线程函数调用失败时均是返回错误码,除了部分返回值为 void 的函数。关于错误码的说明在这里的第 8 小节。
  1. pthread_self
    函数原型:pthread_t pthread_self(void);

功能说明:获取线程 ID。

参数说明:无参数。

返回值说明:如果在主线程中调用该函数会返回主线程的线程 ID,如果在子线程中调用该函数会返回子线程的线程 ID,该函数没有失败的情况。

额外说明:线程 ID 是进程内部识别标志,两个进程间线程 ID 允许相同。

  1. pthread_equal
    函数原型:int pthread_equal(pthread_t t1, pthread_t t2);

功能说明:比较两个线程 ID 是否相等,在 Linux 系统中 pthread_t 都设计为 unsigned long 类型,所以可以直接用 == 判别是否相等,但是如果某些系统设计为结构体类型,那么就可以通过 pthread_equal 函数判别是否相等了。

参数说明:要比较的两个线程 ID。

返回值说明:若相等返回非 0 数值,否则返回 0。

  1. pthread_exit
    函数原型:void pthread_exit(void *retval);

功能说明:将单个线程退出。

参数说明:retval 为该线程的返回状态,如果主线程调用 pthread_join 可以获取到该返回状态。

返回值说明:void。

额外说明:如果在主线程中调用了 pthread_exit(NULL),则主线程退出,如果子线程存在会继续执行。如下代码,就算主线程先退出了,也不会影响子线程打印"我是子线程"。注意如果使用 exit 退出会导致整个进程结束。

  1. pthread_join
    函数原型:int pthread_join(pthread_t thread,void **retval);

功能说明:阻塞等待线程退出,获取线程退出状态,相当于进程中的 waitpid 函数,如果线程退出,pthread_join 立刻返回。

参数说明

thread:代表要等待线程的线程 ID

retval:获取该线程的退出状态

返回值说明

    成功情况下返回 0,失败则返回错误码。
  1. pthread_detach
    函数原型:int pthread_detach(pthread_t thread);

功能说明:将线程 ID 为 thread 的线程分离出去,所谓分离出去就是指主线程不需要再通过 pthread_join 等方式等待该线程的结束并回收其线程控制块(TCB)的资源,被分离的线程结束后由操作系统负责其资源的回收。

参数说明:thread 为要分离的线程的线程 ID。

返回值说明

    成功情况下返回 0,失败情况下返回错误码。

额外说明

    一般来说,主线程是要负责创建出来的子线程的资源回收工作的。如果主线程先于子线程退出并且子线程没有设置为分离状态,那么子线程结束后其资源是无法得到回收的,会造成资源浪费和系统臃肿;如果主线程先于子线程退出但是子线程时分离状态,那么子线程退出的时候操作系统会自动回收其资源。
  1. pthread_cancel
    函数原型:int pthread_cancel(pthread_t thread);

功能说明:杀死线程。

参数说明:thread 为要杀死的线程的线程 ID。

返回值说明:成功情况下返回 0,失败情况下返回错误码。

程序说明

    分别创建了两个线程,pthread_func3 是一个死循环。在主线程中 sleep(3) 之后调用 pthread_cancel 结束子线程 pthread_func3,再调用 pthread_join 回收该子线程,由于子线程已经被杀死,此时 pthread_join 返回 -1。如果在子线程中的 while(1) 里,将 printf 和 sleep 函数注释掉,会发现杀不死该线程,原因是 pthread_cancel 并不等待线程终止,它仅仅提出了一种请求,需要子线程执行到特定的取消点才能终止该线程(如一些系统调用 write,pause 等地方)。如果线程中没有系统调用的函数,可以加入 pthread_testcancel 函数作为取消点。
  1. 常见错误码
    EDEADLK:检测到线程发生死锁

EINVAL:线程不是可以等待回收的线程(后续会讲到线程分离)或者有其他线程已经准备等待回收该线程了

ESRCH:该线程 ID 不存在

三.使用线程的好处
在 Linux 编程中,多线程编程无疑是十分重要的。它可以提高程序的并发处理能力,线程间通信和共享数据十分方便,而且相对于多进程来说,它更加轻量级、好用。
————————————————
版权声明:本文为CSDN博主「梦别停」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_38102771/article/details/91351126

线程以及pthread库的使用相关推荐

  1. windows下使用pthread库

    最近在看<C++多核高级编程>这本书,收集了些有用的东西,方便在windows下使用POSIX标准进行Pthread开发,有利于跨平台. ------------------------- ...

  2. pthread库进行多线程编程 - 组件工厂 - C++博客

    pthread库进行多线程编程 - 组件工厂 - C++博客 11 Threads 1 Introduction 不用介绍了吧- 2 Thread Concepts 1.     Thread由下面部 ...

  3. c语言 标准多线程库,关于C语言多线程pthread库的功能描述

    与线程相关的说明 һpthread_t pthread_t在头文件/usr/include/bits/pthreadtypes.h中定义: typedef unsigned long int pthr ...

  4. Android线程池封装库

    目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...

  5. android 多线程封装,Android线程池封装库

    目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...

  6. 511遇见易语言API模块线程初始化com库(CoInitialize)

    首先了解一下com组件,这样我们才能明白初始化com库的作用,用到两个API:CoInitialize,CoInitializEX 一.什么是COM组件 1.COM是Component Object ...

  7. boost创建线程池_boost库使用—线程类

    boost库使用-线程类 boost 库中提供了两种创建线程的方式: 一种是单个线程创建,另外一种是线程组的创建,进行线程管理:同时,在线程库中还提供了锁的方式: thread 线程 thread 就 ...

  8. 【原创】多线程应用中pthread库使用问题

    2019独角兽企业重金招聘Python工程师标准>>> 在 linux 下开发多线程应用,大多情况下我们都会使用 pthread (即 POSIX thread)这个库.该库遵循 P ...

  9. 【Linux 内核】进程管理 ( 进程特殊形式 | 内核线程 | 用户线程 | C 标准库与 Linux 内核中进程相关概念 | Linux 查看进程命令及输出字段解析 )

    文章目录 一.进程特殊形式 ( 内核线程 | 用户线程 ) 二.C 标准库与 Linux 内核中进程相关概念 三.Linux 查看进程命令及输出字段解析 一.进程特殊形式 ( 内核线程 | 用户线程 ...

最新文章

  1. 团队-石头剪刀布-模块测试过程
  2. 解决大众点评换设备无法用卷(你本次购买不符合活动规则)的问题
  3. 5个强大的Java分布式缓存框架
  4. android udp 设备发现,两台Android设备之间进行UDP连接(使用多播地址)~~求大神指点...
  5. Nginx记录客户端POST过来的具体信息
  6. Linux内核 触摸板,Linux下关闭触摸板和触摸杆
  7. windows 使用 tricks
  8. 一文看懂阿里、京东、滴滴大数据架构变迁
  9. 小D课堂 - 零基础入门SpringBoot2.X到实战_第14节 高级篇幅之SpringBoot多环境配置_59、SpringBoot多环境配置介绍和项目实战...
  10. idean中jsp页面乱码_IntelliJ IDEA 控制台 乱码 有效解决办法
  11. ws2812b灯带容易坏_树莓派控制WS2812B灯带 - Python
  12. 利用SPSS做数据分析①(了解SPSS)
  13. 58子站安居,经纪人营销管理平台登录接口加密逆向
  14. python面板数据分析代码_面板数据分析是什么如何进行面板数据分析?
  15. Linux 文件后面带星号
  16. 2021鹏业安装算量软件常见问题整理(二十)
  17. LocalDate、LocalDateTime计算时间差
  18. Bottom Sheets
  19. 爬虫入门实战第一站——梨视频视频爬取
  20. 很好用的壁纸网站源码分享,仅供学习,请勿商用。

热门文章

  1. 【转】做好性能测试的6个关注点
  2. DUMPE2FS(8)
  3. IOS UIPageController
  4. 《C语言深度剖析》学习笔记三
  5. 熊猫直播 使用什么sdk_没什么可花的-但是16项基本操作才能让您开始使用熊猫
  6. leetcode 633. 平方数之和(双指针)
  7. leetcode537. 复数乘法
  8. 心理学专业转用户体验_用心理学设计奇妙的用户体验
  9. 轻松学习分布式|系列3|分布式数据库。
  10. Java-JUC(十):线程按序交替执行