深入Linux轻量级进程管理:线程创建、线程ID解析与进程地址空间页表探究

news2024/9/20 16:39:05
🍑个人主页:Jupiter.
🚀 所属专栏:Linux从入门到进阶
欢迎大家点赞收藏评论😊

在这里插入图片描述

在这里插入图片描述

目录

  • `🚲Linux线程控制`
    • `🐏POSIX线程库`
    • `🐕创建线程`
      • `🐟指令查看轻量级进程`
          • `指令:ps -aL`
    • `🐒线程ID及进程地址空间布局`
            • *pthread_t 到底是什么类型呢?*
      • `🦔__thread与线程的局部存储`


🚲Linux线程控制

🐏POSIX线程库

在Linux中,没有线程的概念,只有轻量级进程的概念,所以Linux系统只提供了轻量级进程的系统调用,没有线程相关的系统调用,但是用户不知道轻量级进程的概念,只知道线程和进程,所以Linux将轻量级进程的系统调用进行封装,转成线程相关的接口语义提供给用户,就形成了pthread库

  • 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”开头的。
  • 要使用这些函数库,要通过引入头文<pthread.h>
  • 链接这些线程函数库时要使用编译器命令“-lpthread”选项。

🐕创建线程

  • 功能:创建一个新的线程

  • 原型
    int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);

  • 参数

    • thread:返回线程ID
    • attr:设置线程的属性,attr为NULL表示使用默认属性
    • start_routine:是个函数地址,线程启动后要执行的函数
    • arg:传给线程启动函数的参数(可以是对象等等)
    • 返回值:成功返回0;失败返回错误码
  • 错误检查:

    • 传统的一些函数是,成功返回0,失败返回-1,并且对全局变量errno赋值以指示错误。
    • pthreads函数出错时不会设置全局变量errno(而大部分其他POSIX函数会这样做)。而是将错误代码通过返回值返回pthreads同样也提供了线程内的errno变量,以支持其它使用errno的代码。对于pthreads函数的错误,建议通过返回值判定,因为读取返回值要比读取线程内的errno变量的开销更小。

注意:新线程和主线程谁先运行?这是未知的。

示例代码:

#include <iostream>
#include <unistd.h>
#include <pthread.h>

void *routine(void *name)
{
    std::cout << "i am new thread,name:" << (char *)name << std::endl;
    sleep(1);

    return nullptr;
}
int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, routine, (void *)("thread-1"));

    while (true)
    {
        std::cout << "i am process,pid:" << getpid() << std::endl;
        sleep(1);
    }

    return 0;
}

运行结果:

🐟指令查看轻量级进程

指令:ps -aL

根据上面的结果可知:他们的pid一样,所以属于同一个进程,而且可知:OS在进行调度的时候,用的是LWP进行调度的。(因为pid可能一样,不能唯一性标识)

🐒线程ID及进程地址空间布局

  • pthread_ create函数会产生一个线程ID,存放在第一个参数指向的地址中。

  • 前面讲的线程ID属于进程调度的范畴。因为线程是轻量级进程是操作系统调度器的最小单位,所以需要一个数值来唯一表示该线程。

  • pthread_ create函数第一个参数指向一个虚拟内存单元,该内存单元的地址即为新创建线程的线程ID,属于NPTL线程库的范畴。线程库的后续操作,就是根据该线程ID来操作线程的。

线程库NPTL提供了pthread_ self函数,可以获得线程自身的ID

  • pthread_t pthread_self(void);
pthread_t 到底是什么类型呢?
  • 取决于实现。对于Linux目前实现的NPTL实现而言,pthread_t类型的线程ID本质就是一个进程地址空间上的一个地址

  • 线程的管理库维护,即描述线程的结构体与管理线程的数据结构(类似于数组)就在库里面的,其中pthread_t tid即是描述tid线程结构体的起始地址

  • 线程的栈与局部存储是在库中维护的。虽然栈是线程独立的,但是其他线程也是可以访问的。

示例代码:

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
std::string ToHex(pthread_t tid)   //将id转换为十六进制
{
    char buff[64];
    snprintf(buff, 64, "0x%lx", tid);

    return buff;
}

void *routine(void *name)
{
    while (true)
    {
        sleep(1);
        std::cout << "i am new thread,name:" << (char *)name << "  my tid is :" << ToHex(pthread_self()) << std::endl;
    }

    return nullptr;
}
int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, routine, (void *)("thread-1"));

    while (true)
    {
        std::cout << "i am process,pid:" << getpid() << "  new thread id:" << ToHex(tid) << std::endl;
        sleep(1);
    }

    return 0;
}

运行结果:
在这里插入图片描述

🦔__thread与线程的局部存储

  • __thread 是 C 和 C++ 中用于声明线程局部存储的一个关键字(或属性,具体取决于编译器和平台)。它告诉编译器或链接器,被 __thread 修饰的变量是每个线程私有的,即每个线程都有该变量的一个独立实例,这些实例之间互不影响。如:__thread int tls_variable = 0; 一般对于全局变量使用。
    示例代码:
#include <pthread.h>  
#include <stdio.h>  
  
// 声明一个线程局部变量  
__thread int tls_variable = 0;  
  
void* thread_function(void* arg) 
{  
    tls_variable = (int)arg; // 每个线程都会修改它自己的 tls_variable 副本  
    printf("Thread %ld has tls_variable = %d\n", (long)pthread_self(), tls_variable);  
    
    return NULL;  
}  
  
int main() {  
    pthread_t threads[2];  
  
    // 创建两个线程,每个线程将接收到一个不同的参数  
    pthread_create(&threads[0], NULL, thread_function, (void*)1);  
    pthread_create(&threads[1], NULL, thread_function, (void*)2);  
  
    // 等待两个线程完成  
    pthread_join(threads[0], NULL);  
    pthread_join(threads[1], NULL);  
  
    return 0;  
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python(TensorFlow)和Java及C++受激发射损耗导图

&#x1f3af;要点 神经网络监督去噪预测算法聚焦荧光团和检测模拟平台伪影消除算法性能优化方法自动化多尺度囊泡动力学成像生物研究多维分析统计物距粒子概率算法 Python和MATLAB图像降噪算法 消除噪声的一种方法是将原始图像与表示低通滤波器或平滑操作的掩模进行卷积。…

汇编伪指令 GNU 风格(24)

先来看看关于标号的内容。 这里的局部标号是需要注意的。 全局标号&#xff0c;以及注释 可以不看。 来看一个例子&#xff1b; 这里的 BSYM 我不知道是什么意思。 在来看看关于伪操作的内容&#xff0c; 一般是以 . 开头的。 这是基本的一些操作。 然后是举例&#xff1a; …

前后端时间正确传递

引言&#xff1a;后端传递给前端去展示时间的时候将时间转化为String类型的时间数据去返回。此时就需要加上 JsonFormat 注解来解决这个问题。 框架环境配置中&#xff0c;时间配置为 情形一&#xff1a; 数据库字段exam_time类型为date 后端实体类中examTime类型为Date 1.前…

搭建VUE+VScode+elementUI环境遇到的问题

手把手教你搭建VUEVScodeelementUI开发环境-CSDN博客 vue : 无法加载文件 C:\Users\xxx\AppData\Roaming\npm\vue.ps1&#xff0c;因为在此系统上禁止运行脚本 vue : 无法加载文件 C:\Users\xxx\AppData\Roaming\npm\vue.ps1&#xff0c;因为在此系统上禁止运行脚本 - 知乎 更…

Django+Vue家居全屋定制系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 需要的环境3.2 Django接口层3.3 实体类3.4 config.ini3.5 启动类3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质创作者&…

虚拟机苹果系统MacOS中XCode的安装

1、背景介绍 主机系统Win11&#xff0c;虚拟机VMWare17&#xff0c;苹果系统MacOS 13.6.7 2、Xcode的在线 点击应用市场&#xff0c;输入Xcode搜索&#xff1a; 看来Xcode无法安装在macOS V13上&#xff0c;直接在线安装失败。 3、采用下载安装包的方法进行安装 解决办法参考链…

Linux操作系统下的一些常用命令分享(ubuntu16.04)

注意一般Linux命令字符与字符之间都是空格来隔开的&#xff0c;所以千万不能忘记打空格&#xff0c;而且Linux区分大小写。&#xff08;目录就是文件夹&#xff09; 1、pwd 查看当前所在目录 2、查看帮助 命令 --help 但是这个命令会把所有内容一次性全部显示我们看帮助时很…

Linux远程管理工具推荐

原文阅读:【巨人肩膀社区专栏分享】Linux远程管理工具推荐 前两天xshell不让用了&#xff0c;刚好一台新电脑要装一个远程连接工具&#xff0c;准备试试其他。网上找了一些资料整理如下。 欢迎各位看官评论区说出你在使用的工具&#xff0c;期待你的使用经验分享&#xff08;…

Git的基本使用(持续更新)

基本使用 创建仓库 命令&#xff1a;git initgit init&#xff1a;将当前文件夹作为Git仓库&#xff0c;并在该文件夹中生成一个.git目录&#xff0c;该目录包含了资源的所有元数据&#xff0c;不可修改里面的内容。 git init newWareHouse&#xff1a;新建一个newWareHouse…

JVM性能监控和调优

JVM性能监控和调优 文章目录 JVM性能监控和调优性能优化的步骤GC日志分析GC日志参数测试GC分类日志结构 OOM&#xff1a;堆溢出模拟堆溢出dump文件分析gc日志分析 OOM&#xff1a;元空间溢出模拟元空间溢出dump文件分析原因及解决方案 OOM&#xff1a;GC overhead limit exceed…

python学习第二节:安装开发工具pycharm

python学习第二节&#xff1a;安装开发工具pycharm 1.下载安装包&#xff1a;https://www.jetbrains.com/pycharm/ 点击 Download 下滑页面到下面的社区版&#xff0c;&#xff08;上面的专业版是收费的&#xff0c;下面的社区版是免费的&#xff09; 2.安装 点击安装文件 …

计算机基础知识复习9.5

数据交换 电路交换&#xff1a;交换信息的两个主机之间简历专用通道&#xff0c;传输时延小&#xff0c;实时性强&#xff0c;效率低&#xff0c;无法纠正错误。 报文交换&#xff1a;信息拆分成小包(报文&#xff09;大小无限制&#xff0c;有目的/源等信息提高利用率。有转…

C++入门项目:Linux下C++轻量级Web服务器 跑通|运行|测试(小白进)

TinyWebServer是一个开源的项目&#xff0c;适合小白入门C网络编程&#xff0c;注意该项目是在linux系统下。 Linux下C轻量级Web服务器&#xff0c;助力初学者快速实践网络编程&#xff0c;搭建属于自己的服务器. 使用 线程池 非阻塞socket epoll(ET和LT均实现) 事件处理(R…

时钟分频流程

具体流程&#xff1a; 外部晶振&#xff08;XTIpll&#xff09;和 外部时钟&#xff08;EXTCLK&#xff09;经过OM【3&#xff1a;2】选择进入时钟模块 我们可以看到&#xff0c;在不同的模式下会选择不同的时钟源和状态。 时钟信号进入锁相环(PLL)后&#xff0c;会改…

Java项目:139 springboot基于SpringBoot的论坛系统设计与实现

项目介绍 论坛系统设置的角色有管理员&#xff0c;版主&#xff0c;用户等。 管理员管理论坛&#xff0c;主要是对论坛帖子增删改查以及对论坛帖子回复进行查看&#xff0c;对版主和用户进行管理&#xff0c;管理新闻等。 版主可以发布帖子&#xff0c;可以查询论坛帖子&…

Stage 模型应用程序包的结构

AppScope 目录是工具自动生成的 Module 则是工具自动生成的 entry、library&#xff0c;也可以自定义。 Module 类型 Module 有两种类型&#xff1a; Ability 类型的 Module&#xff1a;用来实现应用功能和特性&#xff0c;每一个 Ability 类型的 Module 编译以后。生成一个…

【C++ Primer Plus习题】11.5

问题: 解答: main.cpp #include <iostream> #include "Stonewt.h" using namespace std;int main() {Stonewt incognito 275;cout << "incognito: " << incognito << endl;Stonewt wolfe(285.7);cout << "wolfe: &qu…

Spring Boot技术在医疗排班系统开发中的创新

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 在这里插入图片描述 …

Web入门-08.Tomcat-基本使用

一.Tomcat的基本使用 二.Tomcat使用时的常见问题 Tomcat默认占用8080端口 如果占用8080端口的进程不方便被关闭掉&#xff0c;那么便配置Tomcat端口号(conf/server.xml) 三.Tomcat部署项目

机器学习之 PCA降维

1.PCA 降维简介 主成分分析&#xff08;Principal Component Analysis, PCA&#xff09;是一种统计方法&#xff0c;用于在数据集中寻找一组线性组合的特征&#xff0c;这些特征被称为主成分。PCA 的目标是通过变换原始特征空间到新的特征空间&#xff0c;从而减少数据的维度&…