Linux -- 线程的优点、pthread 线程库

目录

线程的优点

pthread 线程库 

前言

认识线程库

简单验证线程的独立栈空间


线程的优点

与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少得多。

调度进程时,CPU 中有一个 cache(缓存,提高运行效率),CPU在虚拟地址转物理地址后,在内存中找到了一行代码,然而程序在运行时,比如运行到了第50行代码,下一次大概率会运行下一行代码,也就是第51行代码,也有可能跳转到其他代码,但是大概率还是运行下一行代码,所以系统把第50行代码的周边代码都加载到 cache 中,CPU 在运行时直接从 cache 中读取代码,提高 CPU 寻址效率。

进程切换时,会把当前缓存到 cache 的数据都切换掉,而线程切换时,寄存器中的数据会被切换,但 cache 中的数据不会被丢弃,大概率还是可以用的,线程切换只需要更改少量寄存器和栈指针等信息,而不需要像进程那样进行完整的上下文切换。所以线程切换时操作系统做的工作比进程的切换少。

创建一个新线程的代价要比创建一个新进程小得多,线程占用的资源比进程少得多。

进程是资源分配的基本单位,线程是调度的基本单位,当多个线程属于同一个进程时,它们会共享以下资源:

  1. 地址空间:包括代码段、数据段、堆区和栈区(每个线程有自己的栈)。所有线程都可以访问进程的整个虚拟地址空间,这意味着它们可以读写相同的全局变量和静态变量。

  2. 打开的文件描述符:如文件、网络连接等。所有线程都能操作这些描述符,因此对文件或网络连接的操作可以在不同线程间共享。

  3. 环境变量:进程启动时设置的环境变量是所有线程共有的。

  4. 内存映射:如果进程使用了内存映射文件或其他形式的内存映射,那么这些映射也是所有线程可见并可访问的。

  5. 信号处理程序:虽然信号通常是针对整个进程的,但某些信号(如SIGSEGV)可以由特定线程捕捉到,并且线程可以安装自己的信号处理器。

  6. 当前工作目录:所有线程共享同一进程的工作目录,任何线程改变工作目录都会影响其他线程。

  7. 用户ID和组ID:与安全性和权限相关的标识信息是所有线程共有的。

  8. 资源限制:例如最大文件大小、CPU时间等,这些限制适用于整个进程,因此也适用于所有线程。

因为多个线程共享资源,所以一个线程占用的资源比进程少。

但是线程也会有自己私有的资源

  1. 栈空间每个线程都有自己的栈,用于存储函数调用时的局部变量、返回地址等信息。这是线程之间保持独立性的关键之一,因为每个线程可以在其栈上进行独立的操作而不干扰其他线程。

  2. 寄存器集合(上下文数据):当线程被调度执行时,它有自己的寄存器集,包括程序计数器(PC)、堆栈指针和其他通用寄存器。这些寄存器保存了线程执行的状态信息。

  3. 线程ID:操作系统赋予每个线程一个唯一的标识符(TID),用于区分不同的线程。这个ID是线程私有的,因为它唯一地识别了一个线程。

  4. 线程优先级和调度属性:某些系统允许为每个线程设定独立的调度参数,如优先级和策略,这些属性影响线程的执行顺序和时间片分配。 

pthread 线程库 

前言

Linux 的线程是用进程模拟的,线程在Linux底层被视为轻量级进程。对于同一个进程中的新、主线程,可以看出线程的 tid 和 LWP 的数值是不一样的:

线程被创建、等待、分离、终止,且拥有独立的栈结构,这些都是系统在管理线程,

1、系统管理线程时,并没有对用户暴露 在系统中线程被视为轻量级进程的事实,用户认为那就是线程;

2、系统中没有线程的概念,只有轻量级进程的概念,用户却能创建管理、操作线程。

能实现以上两点是因为系统对底层的轻量级进程进行了封装,用户能操作线程都是因为有了库,所以在Linux中线程也叫做用户级线程。既然线程因库而起,就应该由库来维护。

认识线程库

为了管理线程,“先描述再组织”,定义线程的控制块 TCB,TCB是操作系统内核用来管理和调度线程的数据结构

#include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

pthread_create 的第一个参数 thread 是一个 pthread_t 类型的输出型参数,函数调用结束后,thread 指向一个虚拟内存单元,该内存单元的地址即为新创建线程的线程 ID,所以 pthread_t 类型的线程 ID 实际上就是一个进程地址空间的一个地址!线程库的后续操作就是根据该线程 ID 来操作线程的,用户也可以调用 pthread_self 函数来获得线程自身的 ID。

线程库中还包含了一系列用于创建、管理和操作线程的函数、类和数据结构。具体来说,一个典型的线程库会提供以下组件:

1. 线程管理

  • 创建线程:函数或构造函数用来启动一个新的线程,通常需要指定要在线程中执行的函数(即线程函数)。

    • 示例:pthread_create() (POSIX Threads)
  • 销毁/终止线程:方法来结束线程的执行,可以是自然结束(当线程函数返回时),也可以是通过特定API强制结束。

    • 示例:pthread_cancel()std::thread::join() 或 std::thread::detach()
  • 等待线程完成:允许主线程或其他线程等待某个特定线程完成其任务。

    • 示例:pthread_join()std::thread::join()

2. 线程同步机制

为了确保多个线程之间安全地共享资源,线程库提供了各种同步工具:

  • 互斥锁(Mutex):防止多个线程同时访问临界区代码段。

    • 示例:pthread_mutex_tstd::mutex
  • 读写锁(Read-write Locks):允许多个读者或单个写者访问资源。

    • 示例:pthread_rwlock_t
  • 条件变量(Condition Variables):用于线程间的通信,一个线程可以在满足特定条件时唤醒另一个线程。

    • 示例:pthread_cond_tstd::condition_variable
  • 信号量(Semaphores):控制对有限数量资源的访问。

    • 示例:sem_t (POSIX Semaphores)

3. 线程属性设置

  • 设置线程属性:在创建线程之前,可以设定一些线程属性,如栈大小、调度策略等。
    • 示例:pthread_attr_t (POSIX Threads)

4. 线程本地存储(TLS)

  • 线程局部数据:为每个线程提供独立的数据副本,即使这些变量是在全局范围内声明的。
    • 示例:pthread_key_create()pthread_getspecific()pthread_setspecific()std::thread_local (C++)

5. 高级特性

  • 线程池:预先创建一组工作线程,以便快速响应任务请求而不必频繁创建和销毁线程。

    • 示例: C++ 中可以通过第三方库如Boost实现。
  • 并发容器:线程安全的数据结构,例如队列、堆栈、哈希表等。

    • 示例:std::shared_timed_mutexconcurrent_queue (Intel TBB)
  • 原子操作:提供无锁编程的支持,保证某些操作的原子性。

    • 示例:std::atomic (C++)

6. 工具和辅助函数

  • 当前线程信息:获取当前线程ID等信息。

    • 示例:pthread_self()std::this_thread::get_id()
  • 线程调度:调整线程优先级或让出CPU给其他线程。

    • 示例:sched_yield()std::this_thread::yield()

简单验证线程的独立栈空间

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#include<string>void* newthreadRun(void* args)
{std:string threadname=(char*)args;int cnt=5;while(true){std::cout<<"I am "<<threadname<<",cnt: "<<cnt<<", &cnt: "<<&cnt<<std::endl;cnt--;sleep(1);}return nullptr;
}int main()
{pthread_t tid1;pthread_t tid2;pthread_create(&tid1,nullptr,newthreadRun,(void*)"thread-1");   pthread_create(&tid2,nullptr,newthreadRun,(void*)"thread-2");pthread_join(tid2,nullptr);pthread_join(tid1,nullptr);return 0;
}

同一局部变量的地址不同, 说明每个线程的栈空间都私有一份该变量

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/494869.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos权限大集合,覆盖多种权限类型,解惑权限后有“. + t s”问题!

在 CentOS 系统中&#xff0c;权限管理是操作系统的核心功能之一&#xff0c;确保不同用户和进程对文件、目录以及设备的访问被合理控制。 权限系统主要包括传统的 Unix 权限模型、特殊权限&#xff08;SetUID、SetGID、Sticky 位&#xff09;和更精细的访问控制列表&#xff…

pyinstaller打包资源文件和ini配置文件怎么放

1.如果出现无法成功完成操作&#xff0c;因为文件包含病毒或潜在的垃圾软件&#xff0c;说明你的版本太高&#xff0c;更换pyinstaller版本。 pip install pyinstaller6.2.02.一开始打包的时windows下尽量选择打成文件夹的并且要是带命令行窗口的&#xff0c;容易查看错误。 …

五种msvcr100.dll丢失的解决方法,有效修复msvcr100.dll丢失错误!跟msvcr100.dll错误问题说拜拜!

在日常电脑使用过程中&#xff0c;尤其是运行某些应用程序或游戏时&#xff0c;可能会遇到“msvcr100.dll丢失”的错误提示。这个动态链接库&#xff08;DLL&#xff09;文件是Microsoft Visual C Redistributable for Visual Studio 2010的一部分&#xff0c;对于许多程序的正…

【前端】入门指南:Vue中使用Node.js进行数据库CRUD操作的详细步骤

&#x1f4a5; 欢迎来到我的博客&#xff01;很高兴能在这里与您相遇&#xff01; 首页&#xff1a;GPT-千鑫 – 热爱AI、热爱Python的天选打工人&#xff0c;活到老学到老&#xff01;&#xff01;&#xff01;导航 - 人工智能系列&#xff1a;包含 OpenAI API Key教程, 50个…

【网络安全产品大调研系列】1. 漏洞扫描

1. 为什么会出现漏扫技术&#xff1f; 每次黑客攻击事件进行追溯的时候&#xff0c;根据日志分析后&#xff0c;我们往往发现基本都是系统、Web、 弱口令、配置这四个方面中的其中一个出现的安全问题导致黑客可以轻松入侵的。 操作系统的版本滞后&#xff0c;没有更新补丁&am…

Java爬虫:速卖通(AliExpress)商品评论获取指南

引言 在当今的电商时代&#xff0c;商品评论对于消费者决策有着举足轻重的影响。速卖通&#xff08;AliExpress&#xff09;&#xff0c;作为全球知名的在线零售平台之一&#xff0c;拥有海量的商品评论数据。对于商家而言&#xff0c;能够高效地获取这些评论数据&#xff0c;…

AIDD - 探索语言模型在药物分子生成方面的应用

AIDD - 探索语言模型在药物分子生成方面的应用 今天给大家讲一篇2024年10月在nature communications上发表的一篇关于分子生成的文章。现有的分子生成方法中往往只关注药物的特定属性&#xff0c;导致其适用性受限。因此作者提出了TamGen方法&#xff0c;用于针对特定靶点的分子…

【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit

1、AVCodec 硬解咨询&#xff1f; 在做视频播放硬解适配&#xff0c;这是 demo&#xff1a;https://gitee.com/openharmony-sig/ohos_videocompressor/blob/master/videoCompressor/src/main/cpp/video/decoder/VideoDec.cpp 请问&#xff1a; int32_t VideoDec::SetOutputS…

怎么设置电脑密码?Windows和Mac设置密码的方法

为电脑设置密码是保护个人信息安全的重要措施。无论是Windows系统还是MacOS系统&#xff0c;设置密码的步骤都相对简单&#xff0c;但需要根据不同的操作系统选择不同的方法。 一、Windows系统电脑密码设置 方法一&#xff1a;通过控制面板设置账户密码 点击桌面左下角的“开…

谷歌浏览器的网络安全检测工具介绍

作为全球最受欢迎的浏览器之一&#xff0c;谷歌浏览器不仅提供了快速、便捷的浏览体验&#xff0c;还内置了一系列强大的网络安全检测工具&#xff0c;帮助用户识别潜在的网络威胁&#xff0c;保护个人隐私和数据安全。本文将详细介绍谷歌浏览器中的几项关键网络安全检测功能&a…

一个比RTK或redux更轻量级更易使用的 React 第三方状态管理工具库的配置与使用

本文由作者 Samdy_Chan 原创,未经作者同意,请勿随意转载! 使用轻量级第三方的 React 状态管理库 zustand 管理共享状态数据 在 react 框架应用中,开发者应该大多数都是采用 redux 状态管理工具库来管理应用的共享状态数据,但用过 redux 的人都知道,其配置和使用相当复杂…

菜鸟带新鸟——基于EPlan2022的部件库制作

首先&#xff0c;我们需要了解一些概念&#xff1a; Eplan的部件制作内容 以上内容是制作一个完整的部件所需要的。如果公司要求没有那么严格&#xff0c;我们就可以制作1-4级的内容就可以满足日常的使用啦&#xff01; 部件的创建方式 部件创建方式有4类&#xff1a; 1、单…

Charles安装证书过程(手机)

背景&#xff1a;使用模拟器抓包时&#xff0c;发现https请求无法抓取&#xff0c;需要安装相应证书。我自己是因为模拟器升级了安卓7&#xff0c;发现之前安装的证书无效了&#xff0c;需要重新安装。 参考博客&#xff1a;夜神模拟器12Charles进行Https抓包_模拟器抓包ssl-C…

Windows、CentOS环境下搭建自己的版本管理资料库:GitBlit

可以搭建属于公司内部或者个人的Git服务器&#xff0c;方便程序代码及文档版本管理。 官网&#xff1a;http://www.gitblit.com/ Windows环境下安装 提前已经安装好了JDK。 官网下载Windows版的GitBlit。 将zip包解压到自己想要放置的文件夹下。 建立版本库路径&#xff0c…

数据库操作【JDBC HIbernate Mybatis】

JDBC JDBC编程 在java开发中&#xff0c;以前都是通过JDBC&#xff08;Java Data Base Connectivity&#xff09;与数据库打交道的&#xff0c;至少在ORM&#xff08;Object Relational Mapping&#xff09;框架没出现之前是这样&#xff0c;目前常用的ORM框架有JPA、hibernat…

Linux 常见用例汇总

注&#xff1a;本文为 Linux 常见用例文章合辑。 部分内容已过时&#xff0c;未更新整理。 检查 Linux 上的 glibc 版本 译者&#xff1a;joeren | 2014-11-27 21:33 问&#xff1a;检查 Linux 系统上的 GNU C 库&#xff08;glibc&#xff09;的版本&#xff1f; GNU C 库&…

web-密码安全口令

目录 一、密码安全概述 二、密码安全现状 三、破解方式 四、暴力破解 五、字典破解 六、密码字典 学习心得&#xff1a; 一、密码安全概述 现在很多地方都是以用户名&#xff08;账号&#xff09;和口令&#xff08;密码&#xff09;作为鉴权的方式&#xff0c;口令&am…

工控触摸屏用winForms来构建框架,效果还是很不错的

工控触摸屏采用 winForms 构建框架具有诸多优势。winForms 提供了丰富的控件和强大的开发工具&#xff0c;使得界面设计更加高效。它具有良好的稳定性和兼容性&#xff0c;能够适应工控环境的复杂要求。通过 winForms 可以实现直观的操作界面&#xff0c;方便操作人员进行监控和…

开发一个DApp项目:DeFi、DApp开发与公链DApp开发

随着区块链技术的快速发展&#xff0c;去中心化应用&#xff08;DApp&#xff09;逐渐成为创新技术的核心之一。DApp能够利用区块链去中心化的特点&#xff0c;提供更高的安全性、透明性和效率&#xff0c;吸引了越来越多的开发者和投资者关注。本文将围绕如何开发一个DApp项目…

网络下载ts流媒体

网络下载ts流媒体 查看下载排序合并 很多视频网站&#xff0c;尤其是微信小程序中的长视频无法获取到准确视频地址&#xff0c;只能抓取到.ts片段地址&#xff0c;下载后发现基本都是5~8秒时长。 例如&#xff1a; 我们需要将以上地址片段全部下载后排序后再合成新的长视频。 …