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线程知识总结 的相关文章

  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有
  • Raspberry 交叉编译 - 执行程序以“分段错误”结束

    我有一个自己编写的程序 我想从我的 x86 机器上为 Raspberry Pi 构建它 我正在使用 eclipse 生成的 makefile 并且无法更改此内容 我已经阅读了 CC for raspi 的教程 Hackaday 链接 htt
  • 使用 inotify 的正确方法是什么?

    我想使用inotifyLinux 上的机制 我希望我的应用程序知道文件何时aaa被改变了 您能给我提供一个如何做到这一点的示例吗 文档 来自监视文件系统活动 inotify https developer ibm com tutorials
  • 在 Linux 上访问 main 之外的主要参数

    是否可以访问参数main在外面main 即在共享库构造函数中 在 Linux 上除了通过解析之外 proc self cmdline 您可以通过将构造函数放入 init array部分 功能在 init array 不像 init 使用相同
  • 如何访问 mmaped /dev/mem 而不导致 Linux 内核崩溃?

    我有一个简单的程序 尝试访问用户空间中的物理内存 其中内核存储第一个结构页 在 64 位机器上 该地址是 内核虚拟地址 ffffea0000000000 物理地址 0000620000000000 我正在尝试通过用户空间中的 mmap 访问
  • 错误:命令“c++”失败,退出状态为 1

    所以我尝试按照以下说明安装 Pyv8https andrewwilkinson wordpress com 2012 01 23 integrating python and javascript with pyv8 https andre
  • 如何在 Linux 中重新添加 unicode 字节顺序标记?

    我有一个相当大的 SQL 文件 它以 FFFE 的字节顺序标记开头 我使用 unicode 感知的 linux 分割工具将此文件分割成 100 000 行块 但是当将这些传递回窗口时 它确实not与第一个部分以外的任何部分一样 只是它具有
  • 如何重命名 .tar.gz 文件而不提取内容并在 UBUNTU 中创建新的 .tar.gz 文件?

    我有一个命令将创建一个新的 tar gz现有文件中的文件 sudo tar zcvf Existing tar gz New tar gz 该命令将创建一个新的New tar gz从现有的文件Existing tar gz file 谁能告
  • 如何从远程 ssh 连接上运行的 tmux(复制模式)复制到本地剪贴板

    我通过 OS X 上的 VirtualBox 运行 Linux 我通过在无头状态下运行虚拟机 然后使用端口转发 sshing 到 Linux 机器来实现这一点 现在 无论复制到我的虚拟机上的剪贴板 我都可以粘贴到我的远程 ssh 会话上 但
  • 运行此处编译的 C 程序会导致在另一台服务器上找不到 GLIBC 库错误 - 是我的错还是他们的错?

    此处编译的 C 程序在我们的 Ubuntu 服务器上运行良好 但是当其他人尝试在他们的特定 Linux 服务器上运行它时 他们会收到以下错误 myprog install lib tls libc so 6 version GLIBC 2
  • 在 debian wheezy amd64 上安装 ia32-libs

    我正在使用 Debian 7 喘息 amd64 uname a Linux tzwm debian 3 2 0 4 amd64 1 SMP Debian 3 2 51 1 x86 64 GNU Linux 我想安装ia32 libs在我的
  • 可以作为命令行参数传递多少数据?

    在 Linux 下生成进程时可以发送多少字节作为命令行参数 gahooa 推荐了一篇好文章http www in ulm de mascheck various argmax http www in ulm de mascheck vari
  • SMP 上如何处理中断?

    SMP 对称多处理器 多核 机器上如何处理中断 内存管理单元是只有一个还是多个 假设两个线程 A 和 B 运行在不同的内核上 同时 访问页表中不存在的内存页面 在这种情况下 将会出现页面错误 并从内存中引入新页面 将会发生的事件的顺序是什么
  • 如何列出 nginx 中的所有虚拟主机

    有没有一个命令可以列出 CentOS 上 nginx 下运行的所有虚拟主机或服务器 我想将结果通过管道传输到文本文件以用于报告目的 我正在寻找与我用于 Apache 的命令类似的命令 apachectl S 2 gt 1 grep 端口 8
  • 如何在文件夹中的 xml 文件中 grep 一个单词

    我知道我可以使用 grep 在这样的文件夹中的所有文件中查找单词 grep rn core 但我当前的目录有很多子目录 我只想搜索当前目录及其所有子目录中存在的所有 xml 文件 我怎样才能做到这一点 我试过这个 grep rn core
  • 为什么默认情况下不启用 arp 忽略/通告 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我有一个需要经验才能回答的具体问题 为什么 arp ignore arp announce 在 Linux 安装 例如 debian 上默认不启用 有
  • Grep 递归和计数

    需要在具有大量子目录的目录中搜索文件内的字符串 我在用着 grep c r string here 我怎样才能找到总数量 如何仅输出至少具有一个实例的文件 使用 Bash 的进程替换 这给出了我认为是您想要的输出 如果不是 请澄清问题 gr
  • 为什么 call_usermodehelper 大多数时候都会失败?

    从内核模块中 我尝试使用 call usermodehelper 函数来执行可执行文件 sha1 该可执行文件将文件作为参数并将文件的 SHA1 哈希和写入另一个文件 名为输出 可执行文件完美运行 int result 1 name hom
  • 如何回忆上一个 bash 命令的参数?

    Bash 有没有办法回忆上一个命令的参数 我通常这样做vi file c其次是gcc file c Bash 有没有办法回忆上一个命令的参数 您可以使用 or 调用上一个命令的最后一个参数 Also Alt can be used to r
  • 查找并删除超过 x 天的文件或文件夹

    我想删除超过 7 天的文件和文件夹 所以我尝试了 17 07 14 email protected cdn cgi l email protection find tmp mindepth 1 maxdepth 1 ctime 7 exec

随机推荐

  • 运维之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 编程头文件