Linux线程知识总结

2023-10-31

1.编程头文件<pthread.h>,在gcc编译时还需要主动附加库,比如 “gcc a.c -lpthread -o a” 这样

2.线程创建函数

int pthread_create (pthread_t *tid, pthread_attr_t *attr,  void *(*start_rtn)(void *), void* arg);

参数说明:

        pthread_t *tid                        //线程ID,与进程PID是不同的概念

        pthread_attr_t *attr               //线程属性,NULL:线程调度方式和优先级都默认继承父线程,也可以进行配置将线程设置为RT、RR等不同调度方式的线程,并设置指定优先级

        void *(*start_rtn)(void *)        //所创建线程的实体函数,参数需要指定为void*

        void* arg                               //默认NULL,需要传参就给参数

        return                                    //创建成功返回0,创建失败返回非0

3.线程的结合与分离

概念:

        线程分为可结合(joinable)和分离的(detached)两种。

        可结合的线程能够被其他线程回收其资源和杀死,在被其他线程回收之前,它的存储器资源(如栈)是不可释放的。

        分离的线程是不能

int pthread_join(pthread_t thread, void **retval);

        参数说明:

                pthread_t thread;      //线程ID

                void **retval;             //指向一个指向被连接线程的返回码的指针的指针,NULL就可以了

                return;                       //线程结束返回0,失败返回非0           

够被其他线程杀死回收或杀死,它的存储器资源在它终止时由系统自动释放。   

实现方式:

        线程的默认属性是可结合的,即需要其他线程回收其资源。使用pthread_join()函数等待该线程终止,并释放资源后函数才返回,其过程是阻塞的。

int pthread_join(pthread_t thread, void **retval);

参数说明:

       pthread_t thread;      //线程ID

       void **retval;             //指向一个指向被连接线程的返回码的指针的指针,NULL就可以了

       return;                       //线程结束返回0,失败返回非0           

        分离线程可在线程被创建后,在线程函数内设置。使用pthread_detach(pthread_self())来更改自身属性为分离的。分离线程是不可被其他线程终止的。                                                 

4.可结合线程的终止pthread_cancel()               

        分离线程只能自身结束,其他线程是无法结束分离线程的运行的。可结合线程是可以被其他线程所终止的,其他线程可以通过pthread_cancel()函数来向指定线程发送结束的消息,被指定的线程会取消运行,然后返回。发送线程还需要用pthread_join来回收资源。

        取消点:在一个时间段内,程序被挂起时,可以被取消的一个时间点。当线程出现block(阻塞)时,这个被阻塞的地方就是可以被取消的地方。举例:线程A执行过程中,如果遇到线程B执行pthread_cancel (),线程A会继续运行,直到某一行代码出现阻塞(如:pthread_testcancel、pthread_join、pthread_cond_wait、printf、sleep、read、write等都是可以产生阻塞的函数),此时就会退出。 

int pthread_cancel(pthread_t thread);

参数说明:

         pthread_t thread;                //需要终止的线程ID

         return;                           //成功返回0,错误返回errno。会阻塞 

        线程可以设置对cancel信号的反应,线程终止状态cancelstate和线程终止类型canceltype。

 int pthread_setcancelstate(int state,int *oldstate)

 参数说明:

        int state;         //PTHREAD_CANCEL_ENABLE:线程对cancel信号立即有反应,将设置为CANCEL状态(默认)
                           //PTHREAD_CANCEL_DISABLE:线程state设为不可取消,线程不理会信号,继续执行,而使用cancel函数的线程会一直阻塞到可取消状态。
        int *oldstate;     //NULL
                           //不为NULL:获取当前属性
        return;            //成功返回0,错误返回errno。EINVAL:无效state
int pthread_setcanceltype(int type,int *oldtype)
参数说明:
        int type;         //PTHREAD_CANCEL_DEFERRED:运行到下一个取消点就退出(默认)
                          //PTHREAD_CANCEL_ASYNCHRONOUS:直接退出
        int *oldtype;     //NULL
                          //不为NULL:获取原来的属性
        return;           //成功返回0,错误返回errno。EINVAL:无效的type

5.可结合线程异常退出的资源释放问题 

        线程终止有两种情况:正常终止和非正常终止。线程主动调用pthread_exit()或者return退出都将使线程正常退出,这是可预见的退出方式。非正常终止是线程在其他线程干预下,或者由于自身运行出错(比如访问非法地址)而退出,这种退出方式是不可预见的。

        不可预见的终止会存在资源释放问题,比如堆区内存的申请但没有释放,上锁但是没有解锁就异常退出,这是必须要解决的问题。目前可采pthread_cleanup_push()/pthread_cleanup_pop()函数用于自动释放资源。从pthread_cleanup_push()的调用点到pthread_cleanup_pop()之间的程序段中的终止动作(包括调用pthread_exit(0)和取消点终止)都将执行pthread_cleanup_push()所指定的清理函数。

void pthread_cleanup_push(void (*routine)(void*), void *arg)
参数说明:
        void (*rountine)(void*);     //清理函数
        void *arg;                   //传递的回调函数的参数

void pthread_cleanup_pop(int execute)
参数说明:
        int execute;                 //0:非异常退出执行到该函数时,只是弹出清理函数,但并不执行
                                     //1:非异常退出执行到该函数时,弹出清理函数,并执行

        pthread_cleanup_push()/pthread_cleanup_pop()采用先入后出的栈结构管理,清理函数在被调用pthread_cleanup_push()函数时被压入函数栈,在pthread_cleanup_pop()时被弹出函数栈,所以是一个先进后出的策略。pthread_cleanup_push()/pthread_cleanup_pop()可以理解成‘{’和‘}’,在代码结构中要成对出现。

        pthread_cleanup_pop()中execute代表在程序正常调用时,在弹出清理函数决定是否调用的情况。如果execute为0,在程序正常调用到pthread_cleanup_pop(),则只弹出清理函数不执行;反之则弹出清理函数并执行。但线程在通过pthread_exit()和取消点终止时,不论execute为0为1,都会弹出清理函数并执行。而且pthread_cleanup_push()和pthread_cleanup_pop()之前不能存在return退出,这样就不会调用pthread_cleanup_pop(),函数栈就会囤积清理函数,内核会报错。

6.线程调度

        不想写了,用到再总结

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux线程知识总结 的相关文章

  • 何时用引号将 shell 变量括起来?

    我应该或不应该在 shell 脚本中用引号括住变量吗 例如 下列说法正确的是 xdg open URL eq 2 or xdg open URL eq 2 如果是这样 为什么 一般规则 如果它可以为空或包含空格 或实际上任何空格 或特殊字符
  • 如何在 Vim 中突出显示 Bash 脚本?

    我的 Vim 编辑器自动突出显示 PHP 文件 vim file php HTML 文件 vim file html 等等 但是当我输入 vim file在里面写一个Bash脚本 它不会突出显示它 我如何告诉 Vim 将其突出显示为 Bas
  • 如何将一个文本文件拆分为多个 *.txt 文件?

    我有一个文本文件file txt 12 MB 包含 something1 something2 something3 something4 有没有办法分开file txt分成 12 个 txt 文件 比方说file2 txt file3 t
  • 任何退出 bash 脚本但不退出终端的方法

    当我使用exitshell 脚本中的命令 该脚本将终止终端 提示符 有什么方法可以终止脚本然后停留在终端中吗 我的剧本run sh预计通过直接获取或从另一个脚本获取来执行 编辑 更具体地说 有两个脚本run2 sh as run sh ec
  • 对于任何真实数据集,数据压缩比的最小可能值是多少

    我在写信ZLIB类似于嵌入式硬件压缩器的 API 它使用 deflate 算法来压缩给定的输入流 在进一步讨论之前 我想解释一下数据压缩率 数据压缩率定义为未压缩大小与压缩大小之间的比率 压缩比通常大于一 这意味着压缩数据通常比未压缩数据小
  • 更新Linux中的包含路径

    我的 my path to file 文件夹中有几个头文件 我知道如何将这些文件包含在新的 C 程序中 但每次我都需要在包含它之前输入头文件的完整路径 我可以在linux中设置一些路径变量 以便它自动查找头文件吗 您可以创建一个 makef
  • Bash:将字符串添加到文件末尾而不换行

    如何将字符串添加到文件末尾而不换行 例如 如果我使用 gt gt 它将添加到文件末尾并换行 cat list txt yourText1 root host 37 echo yourText2 gt gt list txt root hos
  • Ruby:在 Ubuntu 上安装 rmagick

    我正在尝试在 Ubuntu 10 04 上安装 RMagick 看起来here https stackoverflow com questions 1482823 is there an easy way to install rmagic
  • 链接错误:命令行中缺少 DSO

    我对 Linux 使用 Ubuntu 14 04 LTS 64 位 相当陌生 来自 Windows 并且正在尝试移植我现有的 CUDA 项目 当通过链接时 usr local cuda bin nvcc arch compute 30 co
  • “git add”返回“致命:外部存储库”错误

    我刚刚进入 git 的奇妙世界 我必须提交我对程序所做的一系列更改 位于名为的目录中 var www myapp 我创建了一个新目录 home mylogin gitclone 从这个目录中 我做了一个git clone针对公共回购 我能够
  • /sys/device/ 和 dmidecode 报告的不同 CPU 缓存大小

    我正在尝试获取系统中不同缓存级别的大小 我尝试了两种技术 a 使用 sys device 中的信息 这是输出 cat sys devices system cpu cpu0 cache index1 size 32K cat sys dev
  • 嵌入清单文件以要求具有 mingw32 的管理员执行级别

    我正在 ubuntu 下使用 i586 mingw32msvc 交叉编译应用程序 我很难理解如何嵌入清单文件以要求 mingw32 具有管理员执行级别 对于我的例子 我使用了这个hello c int main return 0 这个资源文
  • Ubuntu Python shebang 线不工作

    无法让 shebang 线在 Ubuntu 中为 python 脚本工作 我每次只收到命令未找到错误 test py usr bin env python print Ran which python usr bin python 在 sh
  • 为什么 Linux 原始套接字的 RX 环大小限制为 4GB?

    背景 我试图mmap 我的原始套接字的 RX 环形缓冲区64 bitLinux 应用程序 我的环由 4096 个块组成 每个块大小为 1MB 总共 4GB 请注意 每个 1MB 块中可以有许多帧 如果您好奇 请参阅此文档了解背景信息 htt
  • 仅使用containerd(不使用Docker)修剪容器镜像

    如果我刚刚containerd安装在 Linux 系统上 即 Docker 是not安装 如何删除未使用的容器映像以节省磁盘空间 Docker 就是这么方便docker system prune https docs docker com
  • 执行命令而不将其保留在历史记录中[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在进行软件开发时 经常需要在命令行命令中包含机密信息 典型示例是将项目部署到服务器的凭据设置为环境变量 当我不想将某些命令存储在命令历史记
  • SSH,运行进程然后忽略输出

    我有一个命令可以使用 SSH 并在 SSH 后运行脚本 该脚本运行一个二进制文件 脚本完成后 我可以输入任意键 本地终端将恢复到正常状态 但是 由于该进程仍在我通过 SSH 连接的计算机中运行 因此任何时候它都会登录到stdout我在本地终
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 通过 Visual Studio 2017 使用远程调试时 Linux 控制台输出在哪里?

    我的Visual Studio 2017 VS2017 成功连接Linux系统 代码如下 include

随机推荐

  • 运维之DNS域名解析服务基础概念与Bind9安装

    0x00 前言简述 基础概念 基础术语 记录类型 0x01 DNS服务介绍 原理流程 实验目标 0x02 DNS服务之Bind9 Ubuntu 安装 CentOS 安装 Docker 容器 1 源码编译安装 2 APT仓库安装 Bind9
  • 游戏介绍网站-网页设计期末结课作业

    一个游戏介绍网站 附资源链接 资源下载链接 介绍 是一个用来介绍个人游戏的主页 适用于移动和PC端 是本人一个前端期末结课作业 软件架构 html css javascript jquery vue 安装教程 无需安装 直接打开即可 使用说
  • 【笔记】Go语言学习笔记

    一 概述 什么是程序 程序 为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合 Go语言 是区块链最主流的编程语言 同时也是当前最具发展潜力的语言 Go语言是Google公司创造的语言 也是Google主推的语言 Googl
  • Mitmproxy 新版配置上游(二级)代理

    Mitmproxy 最新新版配置上游代理 由于在 4 0版本之后flow live change upstream proxy server proxy 方法已经弃用 会引发 AttributeError NoneType object h
  • UGUI之Image、RawImage使用说明

    UGUI之Image RawImage使用说明 Image说明 基本属性 图片切割 九宫格 图集 RawImage可以做什么 用途一 小地图 用途二 帧动画 动图 小常识 Image说明 Image是UGUI中最常见的控件 用于图片的显示
  • golang安装步骤

    1 首先找到资源下载地址 https studygolang com dl 2 下载完毕后 下图是下载好的文件 新建一个文件夹install path 当作安装目录 此处的install file 是下载的资源文件 install path
  • 2021/2/26 单链表应用------一元多项式

    单链表应用 一元多项式 学习时间 2021 2 26 题目名称 单链表应用 一元多项式 问题描述 编写一个程序用单链表存储多项式 并实现两个一元多项式A与B相加的函数 A B刚开始是升序的 A与B之和按降序排列 例如 多项式A 1 2X 0
  • 随机高斯分布的100个2D点

    import numpy as np import matplotlib pyplot as plt 生成随机的10个点 分布在300x300的区域内 num nodes 1000 mean 150 150 高斯分布的均值 cov 500
  • 程序员必读书籍一览表

    书籍推荐 按角色划分 一 软件工程师 Clean Code 代码整洁之道 Implementation Patterns 实现模式 Code Complete 代码大全 Refactoring Improving the Design of
  • 内联函数使用注意事项

    class TableClass private int I j public int add return I j inline int dec return I j int GetNum inline int tableclass Ge
  • uinapp发送和处理二进制数据流

    uinapp发送和处理二进制数据流 将二进制数据流转为json param Object buffer export function buffer to json buffer return JSON parse base64 decod
  • github学习记录目录

    说明 很久没有更新过CSDN了 一方面是因为图片上传和排版过于麻烦 另一方面是因为没有另一方面 懒狗一只 其实是放在GitHub了 CSDN里的东西也不想搬过去 权当重新开始学习啦 平时的学习记录均会不定时的上传到GitHub上 希望走过路
  • 【数据集】——SBD数据集下载链接

    简介 SBD Dataset 是一个语义边界数据集 其包含来自 PASCAL VOC 2011 数据集中 11355 张图片的注释 这些图片均基于 Amazon Mechanical Turk 其中分割之间的冲突均为手动解决 此外 每张图像
  • hadoop之hello world

    初学hadoop 这是第一个例子wordCount import java io IOException import java util StringTokenizer import org apach hadoop conf impor
  • 2022十三届蓝桥杯省赛赛时代码

    1478 14 应该就是取模问题 include
  • 刻章不要钱 5个在线印章制作工具

    俺的博客里的图片 还有网生代上俺写的文章很多都是用印章当作图片水印的 奇怪的是 怎么没人眼馋 有了现代科技 刻章其实很简单了 本文就介绍几个在线印章制作工具 一 MakePic印章生成器 允许输入2 4个汉字 可选择的字体有 经典繁印篆 经
  • 算法导论 学习笔记 第三章 函数的增长

    当输入规模足够大 要研究算法的渐近效率 即我们关心当输入规模无限增加时 在极限中 算法的运行时间如何随着输入规模的变大而增加 主要使用以下渐近记号描述算法的运行时间 1 记号 给定一个函数g n 用 g n 表示以下函数的集合 若存在正常量
  • python之路-untitest单元测试框架组件使用详细介绍

    文章目录 unittest xmind思维导图 UnitTest介绍 TestCase TestSuite TextTestRunner TestLoader TestSuite和TestLoader的使用区别 小结 Fixture 方法级
  • 北京政府占股扶持机构

    1 北京中关村发展集团股份有限公司 2 北京中海投资管理有限公司 http www zhtzgl cn 3 北京首都科技集团有限责任公司 4 亦庄国际 http www etowncapital com zjtz columnsId 40
  • Linux线程知识总结

    1 编程头文件