LInux-多线程基础概念

文章目录

  • 前言
  • 预备
    • 页表详解
      • 缺页中断
      • 页表的映射
  • 一、多线程是什么?
    • 轻量级进程
  • 二、Pthread库
    • pthread_create


前言

从本章的多线程开始,我们开始进入Linux系统的尾声,所以,在学习多线程的过程中,我们也会逐步对之前的内容进行复习,以达到知识巩固的效果。


预备

页表详解

对于我们的已经被编译好的可执行程序,其实早已被按照区域被划分为了4KB为单位,我们称它为页帧

而内存其实也是被划分为了4KB为单位,且内存的IO基本单位也是4KB,我们称内存这样被划分的区域称之为页框

缺页中断

在程序刚开始被运行的时候,我们的数据刚开始都还在磁盘当中,这个时候我们页表所映射的其实是磁盘地址,如果用户这个时候访问一个还在磁盘中的数据,首先要经过页表,然后页表+MMU会发现该数据没有被加载到内存,就会发生缺页中断:先将磁盘的数据加载到内存,然后更改页表映射。

页表的映射

那么为什么页框和页帧为4KB呢? 这就要详细讲解页表是如何映射的。

首先提出一个数学问题,如果只有一个页表单纯地去映射所有地址至少需要多少空间?

在32位系统中,一个地址要占32个bit位并且有多达2^32个地址。
这样计算下来,居然至少多达32GB。所以页表肯定不是这样映射的。
在这里插入图片描述

页表其实被是被划分为N级页表的,在32位系统中,有一级页表和二级页表。

其中一级页表映射后10位bit位,二级页表映射中间的10位bit位。
在这里插入图片描述
通过这样的方式,我们就可以完成页表的映射,我们再来计算一次采用这样的方案需要多少空间。
在这里插入图片描述
这个时候就是MB为单位了,内存存储几十MB还是没有问题的。

一、多线程是什么?

之前我们所学习的信号知识里面,我们了解到了一个进程是可以拥有多个执行流的概念。 那么,一个进程拥有多个执行流有什么用呢? 答案是可以提高程序的工作效率 。

而在我们以往学习所写的代码程序,其实都是单进程单执行流程序。

那么多线程到底是什么? 我们又该如何理解多线程?
在这里插入图片描述
线程在进程内部执行,在进程中的每一个执行流都是一个线程,其中一个进程的每个线程都共享且运行同一份地址空间,在上面的图中,我们可以将一个task_struct理解为一个线程。

对于CPU而言,它的基本调度单位是线程,它调度的其实是线程。

为什么这样工作效率更高?

首先毋庸置疑的,多执行流在CPU中运行肯定比单执行流效率更高。
第二, 因为他们共享一部分数据,不像进程一样具有独立性,所以线程所占用的资源更少。
第三,CPU中有cache缓冲,它会根据局部性原理,会将可能用上的一部分内存数据(/4KB)都保存在CPU的cache区中,所以CPU调用多线程就会使得减少CPU的cache区频繁改变。

可以总结为

1.创建一个新线程的代价要比创建一个新进程小得多
2.与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多
3.线程占用的资源要比进程少很多
4.能充分利用多处理器的可并行数量
5.在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
6.计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
7.I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

轻量级进程

需要注意的是,在Linux系统中,其实并没有真正的线程概念,像Windows其实才具有真正的线程,在Linux系统中,我们采用的是轻量级进程(LWP:Light Weight Process),相对于其他系统的进程内核数据结构更加轻量化,并且也能达到多线程的效果。
就像上图所展示的,CPU所调度的是task_struct,Linux操作系统并没有为线程写一个数据结构。

线程是OS调度的基本单位,进程是承担OS资源的基本实体。


二、Pthread库

pthread_create

pthread库是一个第三方库,我们可以用它库中的pthread_create函数来在Linux系统中创建多线程。

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

参数 pthread_t *thread 是一个输出型函数,用于输出它创建出的线程的线程id。

typedef unsigned long int pthread_t;

参数 const pthread_attr_t *attr,也是一个输出型函数,用于输出该线程的属性数据。

参数 void* (*start_routine)(void *)是一个函数指针,是一个回调函数。

参数 void* arg 用于传递给void* (*start_routine)(void *)的参数。

示例代码如下

#include <cstdio>
#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <string>void *threadRun(void *args)
{const std::string name = (char*) args;while (1){std::cout << name << " : pid " << getpid() << "\n" << std::endl;sleep(1);}}
int main()
{char name[64];pthread_t tid[5];for (int n = 0; n < 5; n++){snprintf(name, sizeof name, "%s-%d", "thread", n + 1);pthread_create(tid + n, nullptr, threadRun,(void*)name);sleep(3);}while(1){std::cout << "Main thread : pid " << getpid() << std::endl;sleep(3);}return 0;
}

因为pthread是第三方库,所以我们需要链接它的库,我们需要使用

g++ -o mythread mythread.cc -std=c++11 -lpthread

如果我们没有加-lpthread,则会出现下图报错
在这里插入图片描述

通过 ps aL 来查看线程状态

在这里插入图片描述
LWP(light weight process 轻量级进程)就是线程id。 它们的pid相同!


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

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

相关文章

邮件营销新手必读指南?怎样做好邮件营销?

邮件营销的全流程及步骤&#xff1f;做好邮件营销有哪些注意点&#xff1f; 邮件营销作为一种传统却依然高效的推广手段&#xff0c;被众多企业所青睐。对于新手来说&#xff0c;如何开展邮件营销&#xff0c;却是一个值得探讨的话题。AokSend将为你提供一份邮件营销新手必读指…

国家妇女节放假是法定的假日

在这个充满活力和希望的春天&#xff0c;我们迎来了一个特殊的节日——国家妇女节。这是一个属于所有女性的节日&#xff0c;是一个庆祝女性成就、关爱女性权益的时刻。在这个特殊的日子里&#xff0c;我们不禁要问&#xff1a;国家妇女节放假是法定假日吗&#xff1f;让我们一…

Ps:辅助类工具组

工具箱里的辅助类工具为图像编辑和设计提供了重要的支持&#xff0c;能帮助用户更准确地测量、选取颜色或添加注释等。 快捷键&#xff1a;I 吸管工具 Eyedropper Tool 用于从图像中采样颜色。 用户可以通过点击屏幕上的任何点来选取那里的颜色&#xff0c;该颜色随即成为当前的…

Java+SpringBoot+Vue+MySQL实战:打造智能餐厅点餐系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

FreeRTOS学习笔记-基于stm32(2)任务的创建与删除,挂起与恢复

一、任务创建与删除 1、动态任务创建 xTaskCreate( TaskFunction_t pxTaskCode,const char * const pcName,const uint16_t usStackDepth,void * const pvParameters,UBaseType_t uxPriority,TaskHandle_t * const pxCreatedTask ); ①&#xff1a;使用此函数前需将宏 confi…

消息队列以及Kafka的使用

什么是消息队列 消息队列&#xff1a;一般我们会简称它为MQ(Message Queue)。其主要目的是通讯。 ps&#xff1a;消息队列是以日志的形式将数据顺序存储到磁盘当中。通常我们说从内存中IO读写数据的速度要快于从硬盘中IO读写的速度是对于随机的写入和读取。但是对于这种顺序存…

SQL 中 IN 与 <= 且 >= 的效率比较

1. 索引利用 当查询条件中的值是离散的、非连续的&#xff0c;或者是在多个不相邻的范围内时&#xff0c;使用 IN 可以更高效&#xff0c;因为 IN 可以直接跳到索引中的这些特定值。而 < 且 > 通常用于连续范围的查询&#xff0c;如果查询的是一个连续的区间&#xff0c…

2024年:AI领航研发新纪元

导言&#xff1a; 在21世纪的科技巨浪中&#xff0c;人工智能&#xff08;AI&#xff09;已经崭露头角&#xff0c;成为研发领域的核心变革者。其强大的潜力和无所不在的应用正在改变人类解决问题的方式&#xff0c;为未来的发展开启了无限可能。随着机器学习、自然语言处理、计…

模型精度fp16和fp32

FP16和FP32是两种不同的浮点数精度格式&#xff0c;在计算机科学特别是深度学习领域中广泛应用。 FP32&#xff08;单精度浮点数&#xff09;&#xff1a; FP32代表32位&#xff08;4字节&#xff09;单精度浮点数格式&#xff0c;这是传统上大多数深度学习模型训练和推理的标准…

代码随想录算法训练营第五十四天|392.判断子序列、115.不同的子序列

392.判断子序列 思路&#xff1a;判断子序列的问题&#xff0c;其实与最大公共子序列的问题是一样的&#xff0c;所以基本上写出来是一样的&#xff0c;但是今天又犯了一个错误&#xff0c;对于非连续子序列&#xff0c;不仅要在相等的时候进行更新&#xff0c;而且不等的时候也…

周立功USBCAN-E-mini分析仪的安装测试笔记

一、介绍 USBCAN-E-mini 智能 CAN 接口卡是系列 USBCAN 便携版本&#xff0c;与 USBCAN—E-U 单路智能 CAN 接口卡完全兼容。USBCAN-E-mini 智能 CAN 接口卡与 USB1.1 总线兼容的&#xff0c;集成 1 路 CAN 接口的智能型 CAN-bus 总线通讯接口卡。采用 USBCAN-E-mini 智能 CAN …

【Linux】Linux操作命令—最全版

目录 一、Linux下基本指令 01. ls 指令 02.cd 指令 03.touch指令 04 mkdir指令 05 man指令 06 cp指令 07 mv指令 08 cat指令 09 more指令 10 less指令 11 head 命令 12 tail 命令 二、时间相关的指令 01 date显示 1.在显示方面&#xff0c;使用者可以设定…

6、string字符串拼接

#include <iostream> using namespace std;void test01 () {string s1 "我";s1 "爱玩游戏";cout << s1 << endl;s1 :;string s2 "lol dnf";s1 s2;cout << s1 << endl;string s3 "i";s3.append(&q…

Vue 使用@别名

1. 安装 types/node types/node 包允许您在TypeScript项目中使用Node.js的核心模块和API&#xff0c;并提供了对它们的类型检查和智能提示的支持。 npm install types/node --save-dev 比如安装之后&#xff0c;就可以导入nodejs的 path模块&#xff0c;在下面代码 import pat…

【ICCV】AIGC时代下的SOTA人脸表征提取器TransFace,FaceChain团队出品

一、论文 本文介绍被计算机视觉顶级国际会议ICCV 2023接收的论文 "TransFace: Calibrating Transformer Training for Face Recognition from a Data-Centric Perspective" 论文链接&#xff1a;https://arxiv.org/abs/2308.10133 开源代码&#xff1a;https://an…

GAMMA电源维修高压直流电源ES30P-5W ES系列

美国Gamma高压电源维修型号&#xff1a;D-ES30R-10N-5W/M&#xff0c;LXR30-1N&#xff0c;XRM5N-100W&#xff0c;ES50P-10W/DDPM&#xff0c;ES60P-10W/DDPM&#xff0c;RR20-20P/DDPM&#xff0c;ES30P-10W&#xff0c;ES60P-10W DDPM&#xff0c;RR60-18P/220V&#xff0c;…

快看!提高效率,还得看工作流表单引擎

经常有客户会问我们&#xff1a;究竟用什么样的工具才能打破信息孤岛&#xff0c;让大家互联联络起来&#xff1f;其实&#xff0c;说到这&#xff0c;有不少人会联想到低代码技术平台。不错&#xff0c;在快节奏的发展社会中&#xff0c;高效率的办公目的已经是大家的追求和发…

java的参数传递机制(引用类型)

1.除了非引用类型的形参传递&#xff0c;还有引用类型的变量形参传递&#xff0c;但引用类型的形参变量传递与非引用类型是不同的&#xff01;&#xff01;&#xff01; public class MethodDemo2 {public static void main(String[] args) {int[] arr new int[]{10,20,30,9}…

邮寄收款码申请所需时间详解

在移动支付风靡的今天&#xff0c;收款码作为连接线上支付与线下商业活动的重要桥梁&#xff0c;已成为众多商家的必备工具。然而&#xff0c;对于初次接触收款码的商家来说&#xff0c;如何申请、需要准备哪些材料以及申请流程需要多长时间等问题&#xff0c;往往成为他们关注…

nginx 端口转发8848的nacos,达到不暴露nacos端口进行web访问nacos

一些客户端原因&#xff0c;云主机未开放8848端口&#xff0c;我们无法直接访问8848/nacos&#xff0c;进行nacos的配置 方法&#xff1a; 以docker启动的nginx和nacos(2.0.3)为例 配置nginx 80端口&#xff0c;配置转发到内网的IP和8848端口&#xff0c;172.17.0.1为docker…