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() 用于获取用户态线程的tidvoid * 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.ccg++ -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://xiahunao.cn/news/3245704.html

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

相关文章

人类或是低等生物?

自工业革命以来&#xff0c;人类对自然资源的消耗日益加剧&#xff0c;引发了对未来可持续性的深刻担忧。然而&#xff0c;一项振奋人心的发现为人类提供了新的希望——一颗名为LHS 1140 b的超级地球&#xff0c;它位于距离地球约48光年的鲸鱼座&#xff0c;由詹姆斯韦布空间望…

uniapp字符串转base64,无需导入依赖(多端支持)

使用示例 import { Base64Encode, Base64Decode } from "@/utils/base64.js" base64.js const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";export const Base64Encode = (text)

Qt Creator的好用的功能

&#xff08;1&#xff09;ctrlf&#xff1a; 在当前文档进行查询操作 &#xff08;2&#xff09;f3: 找到后&#xff0c;按f3&#xff0c;查找下一个 &#xff08;3&#xff09;shiftf3: 查找上一个 右键菜单&#xff1a; (4)f4&#xff1a;在…

使用vcXsrv可视化pcl文件

1、下载vcXsrc程序 2、按下面步骤配置 3、按上面操作后&#xff0c;在运行菜单就能看到它在运行了 4、去wsl中配置&#xff0c;即设置环境变量 vim ~/.bashrc # 设置连接windows的VcXsrv export DISPLAY192.168.1.100:0.0 #&#xff08;192.168.1.100是我windows的ip&#x…

信创学习笔记(四),信创之数据库DB思维导图

创作不易 只因热爱!! 热衷分享&#xff0c;一起成长! “你的鼓励就是我努力付出的动力” 一. 信创学习回顾 1.信创内容 信创内容思维导图 2.信创之CPU芯片架构 信创之CPU芯片架构思维导图 3.信创之操作系统OS 信创之操作系统OS思维导图 二. 信创之国产数据库DB思维导图 …

LAST_INSERT_ID使用方法-(DM8达梦数据库)

LAST_INSERT_ID使用方法 - DM8达梦数据库 1 示例 11.1 创建表1.2 结果集 2 示例 22.1 创建表2.2 结果集 3 达梦数据库学习使用列表 1 示例 1 1.1 创建表 DROP TABLE AT240715; CREATE TABLE "SYSDBA"."AT240715" ( "ID" INT PRIMARY KEY AUTO_…

Autosar Dcm配置-0x28服务ComControl-基于ETAS软件

文章目录 前言DcmDcmDsdDcmDspBswMBswMModeRequestPortBswMModeConditionBswMLogicalExpressionBswMActionBswMActionListBswMRule总结前言 0x28服务主要用来控制非诊断报文的通讯,一般在刷写预编程过程中,用来禁止APP的通信报文,可以减少总线负载率,提高刷写成功率。本文…

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

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

pip install安装第三方库 error: Microsoft Visual C++ 14.0 or greater is required

原因&#xff1a; 在windows出现此情况的原因是pip安装的库其中部分代码不是python而是使用C等代码编写&#xff0c;我们安装这种类型的库时需要进行编译后安装。 安装Microsoft C Build Tools软件&#xff0c;但这种方式对于很多人来说过于笨重。&#xff08;不推荐&#xf…

VUE:跨域配置代理服务器

//在vite.config。js中&#xff0c;同插件配置同级进行配置server:{proxy:{"/myrequest":{//代理域名&#xff0c;可自行修改target:"https://m.wzj.com/",//访问服务器的目标域名changeOrigin:true,//允许跨域configure:(proxy,options) > {proxy.on(&…

【Django+Vue3 线上教育平台项目实战】登录功能模块之短信登录与钉钉三方登录

文章目录 前言一、几个关键概念1.HTTP无状态性2.Session机制3.Token认证4.JWT 二、通过手机号验证码登录1.前端短信登录界面2.发送短信接口与短信登录接口3.Vue 设置interceptors拦截器4. 服务端验证采用自定义中间件方式实现5. 操作流程及效果图如下&#xff1a; 三、通过第三…

Flychat:跨越距离的心灵桥梁

在当今这个数字化时代&#xff0c;人们的沟通方式变得越来越多样化&#xff0c;而移动设备的普及更是极大地推动了这一趋势。我们几乎可以随时随地与他人进行交流&#xff0c;分享生活的点滴。然而&#xff0c;在享受这些便捷的同时&#xff0c;我们也时常会遇到一些小困扰——…

Rust 使用 panic! 还是不用 panic!

使用 panic! 还是不用 panic! 那么&#xff0c;该如何决定何时应该 panic! 以及何时应该返回 Result 呢&#xff1f;如果代码 panic&#xff0c;就没有恢复的可能。你可以选择对任何错误场景都调用 panic!&#xff0c;不管是否有可能恢复&#xff0c;不过这样就是你代替调用者…

年化18.9%的创业板趋势策略,使用模块化策略模板重构(代码+数据)

原创文章第590篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 昨天咱们分享的文章&#xff1a;”以交易为生“&#xff0c;基础设施很重要。 传统backtrader写策略的步骤是如下&#xff1a; 1、定义因子&#xff0c;比如动量roc&#xff1a; …

基于LSTM及其变体的回归预测

1 所用模型 代码中用到了以下模型&#xff1a; 1. LSTM&#xff08;Long Short-Term Memory&#xff09;&#xff1a;长短时记忆网络&#xff0c;是一种特殊的RNN&#xff08;循环神经网络&#xff09;&#xff0c;能够解决传统RNN在处理长序列时出现的梯度消失或爆炸的问题。L…

华为OD算法题汇总

60、计算网络信号 题目 网络信号经过传递会逐层衰减&#xff0c;且遇到阻隔物无法直接穿透&#xff0c;在此情况下需要计算某个位置的网络信号值。注意:网络信号可以绕过阻隔物 array[m][n]&#xff0c;二维数组代表网格地图 array[i][j]0&#xff0c;代表i行j列是空旷位置 a…

基于STM32的智能晾衣设计

1.简介 本设计的目的是开发一种湿度传感智能衣物干燥杆系统&#xff0c;这是一个由单片机控制芯片控制的实时检测系统。该系统使用 DHT11温湿度传感器&#xff0c;检测大气的温度和湿度&#xff0c;然后处理信息&#xff0c;控制电机&#xff0c;完成衣物的收集和干燥工作。  …

相控阵雷达原理详解

相控阵&#xff0c;即相位控制阵列&#xff0c;通过控制阵列各个单元的馈电相位来改变波束指向。 相控阵雷达的原理可以清晰地归纳为以下几点&#xff1a; 1. 基本构成&#xff1a; - 相控阵雷达&#xff0c;即相位控制电子扫描阵列雷达&#xff08;Phased Array Radar, PAR&a…

脚本新手必看!一文掌握${}在Shell脚本中的神操作!

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 变量引用与默认值📝 字符串操作📝 数组与索引📝 参数扩展与模式匹配⚓️ 相关链接 ⚓️📖 介绍 📖 在编程的广阔世界里,隐藏着无数小巧而强大的工具,它们如同魔法般简化着复杂的操作。今天,我将…

抖音换地方IP会马上更新地址吗?解析抖音IP地址变化的真相

随着移动互联网的飞速发展&#xff0c;短视频平台如抖音已深入人心&#xff0c;成为大众生活中不可或缺的一部分。其中&#xff0c;IP地址作为用户在互联网世界的“身份证”&#xff0c;不仅关系到用户的隐私安全&#xff0c;也直接影响着平台内容推送的精准性。当我们跨越地域…