Linux 线程初步解析

1.线程概念

在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列。在linux中,由于线程和进程都具有id,都需要调度等等相似性,因此都可以用PCB来描述和控制,线程含有PCB,没有独立的地址空间,和进程内的其他线程共享地址空间。如下图:

从资源的角度上看,进程是资源分配的基本单位,线程是cpu调度的基本单位。每一个控制线程pcb,我们都可以看成是执行流,执行流可以是线程,也可以是只有一个线程的进程,在Linux中,所有执行流我们都可以看成轻量级进程(LWP)。

2.线程控制函数

首先,我们要了解Linux没有真正意义上的线程,所有执行流都是LWP,因此,为了满足用户对线程使用的需求,Linux的线程库对LWP的接口进行了封装,我们把库里封装好的线程称为用户态线程。

1.pthread_create创建线程

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

第一个参数是输出型参数,输出新线程的用户级线程id,参数2:设置线程的属性,参数3:返回值和参数都为void* 类型的函数指针,参数4:函数参数。创建线程,执行传入的函数。

2.pthread_join等待线程

#include <pthread.h>

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

第一个参数是要等的线程id,第二个是线程执行后返回值 。

3. pthread_exit,pthread_cancel,pthread_self() 

int pthread_exit()线程退出,exit()是进程退出。

int pthread_cancel(pthread_t thread)让某个进程退出

pthread pthread_self() 用于获取用户态线程的tid

4.代码

#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include<time.h>
#include <pthread.h> // 原生线程库的头文件
using namespace std;


// pthread_create(pthread_t &tid, nullptr, handlerTask, td);创建线程的接口
//pthread_join(tid, &ret);线程等待
// pthread_exit()线程退出
//pthread_cancel(tid)取消线程
pthread_self() 用于获取用户态线程的tid

void * handlerTask(void* args)
{
    string s1=(const char*)args;
    sleep(10);
    cout<<"我是"<<s1<<" pid 是 "<<getpid()<<endl;
    cout<<"我的用户级线程id是"<<pthread_self()<<endl;
    string* s2=new string("haha");
    pthread_exit(s2);

}

int main()
{
    cout<<"我是主线程"<<" pid 是 "<<getpid()<<endl;
    cout<<"我的用户级线程id是"<<pthread_self()<<endl;
    const char* s1="新线程";
    pthread_t tid;
    pthread_create(&tid, nullptr, handlerTask, (void*)s1);
    cout<<"新进程用户级id是"<<tid<<endl;
    void *ret=nullptr;
    pthread_join(tid, &ret);
    cout<<"结果为"<<*((string*)ret)<<endl;
}

makefile 文件(注意一定要链接pthread库)

test1:test1.cc
	g++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:
	rm -f test1
	

运行结果:

5.线程分离

  • 默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏。
  • 如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。 
int pthread_detach(pthread_t thread)

可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离.

pthread_detach(pthread_self());

3.用户态线程的实现

在共享区上由pthead动态库来维护,封装了LWP,其中用户级进程的id就是虚拟地址。 

4.资源问题

1.线程私有的:

  • 线程的硬件上下文(cpu寄存器的值)
  • 线程的独立栈结构
  • 线程id
  • 信号屏蔽字
  •  errno 信号屏蔽字
  • 调度优先级

2.线程共享的

  • 内存和地址空间(代码和全局数据)
  • 文件描述符表
  • 每种信号的处理方式(SIG_ IGN、SIG_ DFL或者自定义的信号处理函数)
  • 当前工作目录
  • 用户id和组id

5.线程的优缺点

线程的优点

  • 创建一个新线程的代价要比创建一个新进程小得多(线程的地址内存和地址空间是共享的,只需要创间pcb)
  • 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多(线程切换时由于数据共享,cache不需要重新加载,而进程切换需要重新加载)。
  • 线程占用的资源要比进程少很多
  • 能充分利用多处理器的可并行数量
  • 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
  • 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
  • I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

线程的缺点

  • 性能损失 一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销,而可用的资源不变。
  • 健壮性降低 编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了 不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。
  • 缺乏访问控制 进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。
  • 编程难度提高 编写与调试一个多线程程序比单线程程序困难得多 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp开发钉钉小程序流程

下载开发工具 1、小程序开发工具 登录钉钉开发平台&#xff0c;根据自己的需求下载合适的版本&#xff0c;我这里下载的是Windows &#xff08;64位&#xff09;版本 小程序开发工具 - 钉钉开放平台 2、HBuilder X HBuilderX-高效极客技巧 新建项目及相关配置 新建项目 …

云动态摘要 2024-07-16

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 数据库上云优选 阿里云 2024-07-04 RDS、PolarDB、Redis、MongoDB 全系产品新用户低至首年6折起&#xff01; [免费体验]智能助手ChatBI上线 腾讯云 2024-07-02 基于混元大模型打造&…

智慧煤矿:AI视频智能监管解决方案引领行业新变革

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术已经渗透到各个行业&#xff0c;为传统产业的转型升级提供了强大的动力。在煤矿行业中&#xff0c;安全监管一直是一个重要的议题。为了提高煤矿的安全生产水平&#xff0c;降低事故发生率&#xff0c;智…

远程访问及控制(ssh)

目录 一、OpenSSH服务器 1.1 SSH&#xff08;Secure Shell&#xff09;协议 1.2 OpenSSH 2.1 SSH原理 2.1 1 公钥传输原理 2.1.2 加密原理 2.1.3 SSHD服务的两种验证方式 二、SSH命令中的基本操作 2.1 构建密钥对验证的SSH 2.1.1 公钥和密钥的关系 2.1.2 构建密钥对…

linux虚拟机主ip地址:网络信息不可用(没IP)

第一种情况其它博主写的很详细 就是在 /etc/sysconfig/network-scripts/ifcfg-ens33 的onbootno 改为 yes 然后重启 第二种就是我遇到的&#xff0c;是因为服务没有启动 首先winr打开搜索 然后搜索service.msc 把这两项手工右键开启即可&#xff0c;然后重启虚拟机&a…

安卓笔记1-Retrofit2请求自定义接口

1、整体功能概述 安卓项目中使用Retrofit2实现和自定义接口的网络交互&#xff0c;通过Postman模拟服务端&#xff0c;创建自定义接口。 作用 前后端开发进度对不齐时&#xff0c;客户端可利用本功能模拟测试数据。备忘。 缺点 retrofit模拟接口需要配置响应数据类&#xff…

STM32入门开发操作记录(二)——LED与蜂鸣器

目录 一、工程模板二、点亮主板1. 配置寄存器2. 调用库函数 三、LED1. 闪烁2. 流水灯 四、蜂鸣器 一、工程模板 参照第一篇&#xff0c;新建工程目录ProjectMould&#xff0c;将先前打包好的Start&#xff0c;Library和User文件^C^V过来&#xff0c;并在Keil5内完成器件支持包的…

可视化工具选择指南:助力企业数字化转型和新质生产力发展

随着信息技术的快速发展和新质生产力概念的兴起&#xff0c;可视化工具在各个行业中的作用日益凸显。这些工具不仅能够帮助用户更直观地理解和分析数据&#xff0c;还能提升团队的协作效率和决策质量。 在当今数字化转型迅速发展的背景下&#xff0c;新质生产力的概念正在成为…

策略模式原理与C++实现

定义 定义一些列算法&#xff0c;把他们一个个封装起来&#xff0c;并且使他们可以相互替换&#xff08;变化&#xff09;。该模式使得算法可独立于使用它的客户程序&#xff08;稳定&#xff09;而变化&#xff08;扩展、子类化&#xff09;。 C实现 在不考虑策略模式的情况…

数学基础【俗说矩阵】:齐次线性方程和非齐次线性方程求解-学习笔记

一、矩阵基础知识 二元一次方程的传统解法 不论是代入消元法还是加减消元法都统称 【高斯消元法】。 齐次方程组和非齐次方程组 线性方程组的解 线性方程的向量展示 向量规则 矩阵的高斯消元和初等行变行及其规则 高斯消元规则 初等行变换 矩阵经初等行变换成阶梯矩阵&…

入坑树莓派(2)——树莓派4B与手机蓝牙通信

入坑树莓派(2)——树莓派4B与手机蓝牙通信 1、引言 在入坑树莓派(1)中已经搞掂了可视化问题。现在继续开展下一步,尝试与手机通信,一开始是想弄wifi连接的,但发现基于wifi的APP比较难弄,为了降低开发的难度,又因为树莓派板子自带蓝牙模块,所以直接选用蓝牙连接手机…

SAP 银企直连--FBPM生成付款文件增强

需求描述&#xff1a; SAP中通过运行事务码FBPM生成付款文件&#xff0c;触发传输将文件写入跳板机&#xff0c;写入跳板机之前&#xff0c;检查文件是否已存在&#xff0c;存在则给出提示无需执行 实现步骤 &#xff1a; 文件校验 参照标准函数FI_PAYMEDIUM_SAMPLE_21 创建自…

Vision Pro的增强视觉:企业级Unity插件包实现主摄像头访问

在AR和VR技术的快速发展中,Unity作为跨平台游戏和应用开发的首选引擎,其插件生态的丰富性一直是开发者们关注的焦点。最近,一个专为Vision Pro设计的Unity插件包——EnterpriseCameraAccessPlugin,因其能够通过企业API访问主摄像头的功能,引起了广泛关注。 一、插件背景与…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(二)-支持高分辨率视频直播应用

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…

[Linux] yum和vim

文章目录 yumyum是什么?linux系统&#xff08;Centos&#xff09;的生态 vimvim是什么&#xff1f;vim配置 yum yum是什么? yum是一个下载安装及卸载管理软件的客户端。类似如应用商店 linux系统&#xff08;Centos&#xff09;的生态 Centos下载方式3种&#xff1a;源代…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【26】【内网穿透】cpolar

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【27】【内网穿透】cpolar 内网穿透cpolar内网穿透联调配置练习—使用公网地址访问gulimall.com参考 内网穿透 正常的外网需要访问我们项目的流程是&#xff1a; 买服务器并且有公网固定…

Why can‘t I access GPT-4 models via API, although GPT-3.5 models work?

题意&#xff1a;为什么我无法通过API访问GPT-4模型&#xff0c;尽管GPT-3.5模型可以工作&#xff1f; 问题背景&#xff1a; Im able to use the gpt-3.5-turbo-0301 model to access the ChatGPT API, but not any of the gpt-4 models. Here is the code I am using to tes…

PyCharm在线版,一周使用总结!!!

前言 过去一周&#xff0c;对pycharm在线版进行了使用&#xff0c;对云原生开发工具有了全新的认识&#xff0c;云原生开发是一种现代化的软件开发和部署方法&#xff0c;它充分利用了云计算的优势&#xff0c;特别是容器化、微服务、持续集成/持续部署&#xff08;CI/CD&…

数据结构之线性表表示集合详解与示例(C,C#,C++)

文章目录 基本特征线性表的特点&#xff1a;线性表的表示方法&#xff1a;C、C#和C语言如何实现一个线性表表示集合1. C实现2. C#实现3. C实现 总结 线性表是计算机数据结构中的一个基本概念&#xff0c;它是一种最简单的抽象数据类型。在线性表中&#xff0c;数据元素之间的关…

如何在SpringCloud中使用Kafka Streams实现实时数据处理

使用Kafka Streams在Spring Cloud中实现实时数据处理可以帮助我们构建可扩展、高性能的实时数据处理应用。Kafka Streams是一个基于Kafka的流处理库&#xff0c;它可以用来处理流式数据&#xff0c;进行流式计算和转换操作。 下面将介绍如何在Spring Cloud中使用Kafka Streams实…