操作系统(第五周 第一二堂总结)

news2025/2/8 13:14:44

目录

回顾

前景知识

概述

定义

进程和线程的关系

进程和线程的区别

线程优缺点 

优点:

缺点:

易混概念

 线程实现方式

线程的类型:

​编辑

多线程模型:

线程函数

头文件:

线程创建函数:

线程退出函数:

进程等待线程函数:

终止线程函数:

线程的使用 

线程基本操作(一)

线程基本操作(二)

并发运行 

总结


回顾

上一篇文章讲了两个点:1、进程的运行 2、进程的通信

其中,进程的运行相对更加重要,进程通信中共享内存法的实现相对更加重要

进程的运行包括:进程的创建、工作、被调度、销毁

1、创建:核心在两个函数:fork()创建子进程;exec()让子进程“脱离”父进程,变为相对独立

2、工作:核心在于理解父子进程的并行

3、被调度:核心在于理解进程的五个状态以及状态之间的转变原因

4、销毁:分为主动销毁以及异常销毁

进程的通信 :共享内存法、消息通信法

1、共享内存法:利用双指针模拟的方式实现进程之间的“消息”通信(本质就是一直用while循环,是一种拟通信)

2、消息通信法:需要内核参与,是一种实质性的进程间消息通信

本篇我们就来讲讲线程

前景知识

多个进程之间是并发运行的,多个线程之间是并行运行的

概述

定义

1、线程是CPU使用的一个基本单元,是程序执行基本单位(不代表进程本身不可以执行程序,这个理解很关键!!)

2、线程是进程中的⼀个执⾏单元,负责当前进程中程序的执⾏

进程和线程的关系

1、一个进程可以有很多个线程,但是一个线程只能属于一个进程

2、线程算是进程上下文的一部分

3、一个程序至少有一个进程

进程和线程的区别

1、线程是程序执行的基本单位,进程是CPU分配资源基本单位

2、进程一定归于操作系统管理,线程不一定

3、进程是程序运行的一个实体,程序运行结束进程将自动被收回;线程是进程运行中的一个执行路径(子序列)

线程优缺点 

优点:

1、多条线程在进程中并发运行,由于线程的切换比进程更快,所以在使用者看来线程比进程更接近于并行状态(本质上仍是并发的)

2、响应性好:既然线程更接近并行状态,那么多条线程并行时,其中一条线程堵塞了,其他线程看起来仍处于运行状态,所以仍会给用户提供服务

3、资源共享:线程之间的资源是共享的(例如代码、数据等),而进程需要通过通信来实现共享

4、经济:由于资源共享,所以创建线程更加经济,并且线程的切换所切换的资源也更少

缺点:

1、 编写多线程程序需要非常仔细的设计。在多线程程序中,因时序上细微的偏差或无意造成的变量共享而引发错误的可能性是很大的。
2、 对多线程程序的调试要比单个线程程序的调试困难得多,因为线程之间的交互难以控制。
3、 将大量计算分为两个部分,并把这个两个部分作为不同的线程来运行的程序在一台单处理器机器上并不一定运行得更快(因为本质上CPU一次仍然只能运行一个线程/一个进程),除非是多处理器真正实现多线程并行执行

易混概念

1、线程和进程在一个处理器中是并发执行的,不是并行运行的

2、线程出现后比进程节省资源的重要原因在于:在一个线程被阻塞后CPU切换其他线程的速度更快

3、进程创建线程后,进程本身也仍然和线程并发执行,共同抢占CPU资源

 线程实现方式

线程的类型:

1、完全由用户创建并管理(用户线程) 

2、完全由内核创建并管理(内核线程)

3、由内核和用户共同管理(组合线程)

多线程模型:

1、多对一模型:多个用户线程映射到一个内核线程

2、一对一模型:一个用户线程映射到一个内核线程

3、多对多模型:多个用户线程映射到多个内核线程

上图中:(a)中就是多对一模型(b)中就是一对一模型 (c)中就是多对多模型 

线程函数

头文件:

#include<pthread.h>

线程创建函数:

int pthread_create(pthread_t* thread,const pthread_attr_t* attr,void* (*start_routine)(void*),void* arg);
  • 作用:创建一个线程
  • 参数:
    • 第一个参数thread是新线程的标识符,后续pthread_*函数通过它来引用新进程。其类型的pthread_t定义为:
    • 第二个参数attr用于设置新线程的属性。传递NULL表示使用默认线程属性
    • 第三个参数是返回值、参数变量都为void*的函数指针
    • 第四个参数arg表示新线程的参数

线程退出函数:

        线程函数在结束时最好调用如下函数,该函数通过retval参数向进程的回收者传递其退出信息

void pthread_exit(void* retval);

进程等待线程函数:

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

作用:阻塞进程直到其所有线程运行结束,再开始执行进程
参数:
        thread是目标现成的标识符
        retval是目标线程返回的退出信息
        返回值:成功0,失败返回错误码

终止线程函数:

int pthread_cannel(pthread_t thread);

作用:终止一个线程,即取消线程
参数:
        thread是目标线程标识符
        返回值:成功0,失败返回错误码

线程的使用 

线程基本操作(一)

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
 
void* fun(void* arg)
{
	for(int i=0;i<5;i++)
	{
		printf("fun run\n");
		sleep(1);
	}
}
 
int main()
{
	pthread_t id;
	pthread_create(&id,NULL,fun,NULL);
	for(int i=0;i<2;i++)
	{
		printf("main run\n");
		sleep(2);
	}
	exit(0);
}

执行结果: 

关键点:

1、进程和线程并发运行,抢占CPU资源

2、进程运行结束后,其线程也会被强制结束

3、线程创建需要一定的时间

线程基本操作(二)

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
 
void* fun(void* arg)
{
	for(int i=0;i<5;i++)
	{
		printf("fun run\n");
		sleep(1);
	}
	pthread_exit("fun over\n");//结束时会发送信息给进程
}
 
 
int main()
{
	pthread_t id;//存储线程的id
	pthread_create(&id,NULL,fun,NULL);
	for(int i=0;i<2;i++)
	{
		printf("main run\n");
		sleep(1);
	}
	char* s=NULL;
    pthread_join(id,(void**)&s);//阻塞进程等待线程结束,并得到线程的结束信息
    printf("s=%s",s);
	exit(0);
}

执行结果:

关键点: 

1、利用pthread_join来阻塞进程

2、利用pthread_exit来实现进程和线程的通信(消息传递)

并发运行 

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
 
void* fun(void* arg)
{
	int index=*(int*)arg;
	for(int i=0;i<3;i++)
	{
		printf("index=%d\n",index);
		sleep(1);
	}
 
}
 
int main()
{
	pthread_t id[5];
	int i;
	for(i=0;i<5;i++)
	{
        index[i]=i;
		pthread_create(&id[i],NULL,fun,(void*)&index[i]);//进程先运行结束后,等待线程运行
	}	
	for(i=0;i<5;i++)
	{
        	pthread_join(id[i],NULL);//等待五个线程
	}
	exit(0);
}

执行结果 :

关键点:

1、不同线程并发运行

2、线程创建需要时间,按照现在的CPU速度,进程早已走完了5个循环 

总结

本文到这里就结束啦~~这堂课的内容较为杂乱、复杂,但是学一学拓展一下知识是非常好的呀~~
如果觉得对你有帮助,辛苦友友点个赞哦~

知识来源:操作系统概念(黑宝书)、山东大学高晓程老师PPT及课上讲解。不要私下外传

 

 

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

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

相关文章

k8s控制器(五)_____DaemonSet

DaemonSet控制器 DaemonSet控制器是Kubernetes中的一种控制器&#xff0c;用于确保集群中的每个节点都运行一个Pod的副本。它通常用于在整个集群中部署一些系统级别的服务&#xff1a; 在每一个node节点运行一个存储服务&#xff0c;例如gluster&#xff0c;ceph。在每一个no…

DRF视图组件(2个视图基类、5个视图扩展类、9个视图子类、视图集和路由映射)

DRF视图组件(2个视图基类、5个视图扩展类、9个视图子类、视图集和路由映射) 目录 DRF视图组件(2个视图基类、5个视图扩展类、9个视图子类、视图集和路由映射)2个视图基类mixins的5个视图扩展类generics的9个视图子类视图集自定制返回格式自动生成路由(SimpleRouter)action装饰器…

非监督学习的模型为条件概率分布P(z|x)和p(x|z)的区别

在无监督学习中&#xff0c;假设X是输入空间&#xff0c;Z是输出的隐式结构空间&#xff0c;要学习的模型非概率模型情况可以表示为函数zg(x)&#xff0c;概率模型情况下表示为条件概率分布P&#xff08;z|x&#xff09;或p(x∣z)&#xff0c;它们 都可以用来描述数据中的潜在结…

[ROS 系列学习教程] 建模与仿真 - URDF 语法介绍

ROS 系列学习教程(总目录) 本文目录 一、robot标签二、link标签三、joint标签 URDF文件中使用XML格式描述的机器人模型&#xff0c;下面介绍URDF的XML标签。 一、robot标签 机器人描述文件中的根元素必须是robot&#xff0c;所有其他元素必须封装在其中。 属性 name&#x…

JetBrains Rider 2024.1 发布 - 快速且强大的跨平台 .NET IDE

JetBrains Rider 2024.1 发布 - 快速且强大的跨平台 .NET IDE 请访问原文链接&#xff1a;JetBrains Rider 2024.1 (macOS, Linux, Windows) - 快速且强大的跨平台 .NET IDE&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Jet…

jpa使用Querydsl需要规避的一些坑

在使用Spring Data JPA时&#xff0c;通常会使用Querydsl来构建类型安全的查询。在Querydsl中&#xff0c;为了区分实体类与Querydsl查询类&#xff0c;习惯上会给查询类的前缀添加一个"Q"&#xff0c;表示该类是一个查询类。这样做可以有效地避免实体类与查询类之间…

数据结构和算法(哈希表和图(A*算法精讲))

一 、哈希表 1.1 哈希表原理精讲 哈希表-散列表&#xff0c;它是基于快速存取的角度设计的&#xff0c;也是一种典型的“空间换时间”的做法 键(key)&#xff1a; 组员的编号如&#xff0c;1、5、19。。。 值(value)&#xff1a; 组员的其它信息&#xff08;包含性别、年龄和…

pyqt实现星三角减压启动

这个对于plc上实现是非常容易得。它本来就是逻辑控制器&#xff0c;如果用代码实现它&#xff0c;该怎么做呢&#xff1f;这个实现起来看似简单&#xff0c;实则是有不少坑的&#xff08;大神除外&#xff09;。我一直想用类来封装&#xff0c;让它继承QObject,为啥非要继承QOb…

电信网络如何异地共享文件?

电信异地共享文件是指在不同地区的电信网络下&#xff0c;通过使用特定技术实现文件的共享和传输。在传统的网络环境中&#xff0c;由于网络限制和复杂的网络设置&#xff0c;实现跨地区的文件共享是一个具有挑战性的任务。随着技术的不断进步&#xff0c;现在可以利用电信异地…

Spring Boot | SpringBoot对 “SpringMVC“的 “整合支持“、SpringMVC“功能拓展实现“

目录: SpringMVC 的 “整合支持” ( 引入"Web依赖启动器"&#xff0c;几乎可以在无任何额外的配置的情况下进行"Web开发")1.SpringMVC "自动配置" 介绍 ( 引入Web依赖启动器"后&#xff0c;SpringBoot会自动进行一些“自动配置”&#xff0…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《应用图论建模输电网的电力现货市场出清模型》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

【cuda\cudnn安装教程】以及环境变量设置(以cuda11.8为例)

【cuda\cudnn安装教程】以cuda11.8为例 cuda11.8安装 安装的时候一切都是按默认安装就好&#xff0c;地址也是默认路径 cudnn安装 下载需要登陆&#xff0c;按要求注册就好 将cudnn压缩包中的内容复制到cuda的安装路径中&#xff0c;进行替换&#xff0c;如下图 验证cuda是否…

可视化报表Superset

文章目录 一、Superset入门与安装1、Superset概述2、安装Python环境2.1 安装Miniconda2.2 创建Python3.7环境 3、Superset部署3.1 安装Superset3.2 启动Supterset3.3 superset启停脚本 4、docker部署 二、Superset使用与实战1、对接MySQL数据源2、制作仪表盘与图表 一、Superse…

【Canvas与艺术】绘制斜置黄色三角biohazard标志

【关键点】 径向渐变色和文字按角度偏转。 【成果图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>使用Html5/Canvas绘制…

2024蓝桥A组E题

成绩统计 问题描述格式输入格式输出样例输入样例输出评测用例规模与约定解析参考程序难度等级 问题描述 题目有问题方差定义那加平方&#xff08;vi-v&#xff09; 格式输入 输入的第一行包含三个正整数n,k,T &#xff0c;相邻整数之间使用一个空格分隔。 第二行包含n个正整数…

使用go和消息队列优化投票功能

文章目录 1、优化方案与主要实现代码1.1、原系统的技术架构1.2、新系统的技术架构1.3、查看和投票接口实现1.4、数据入库MySQL协程实现1.5、路由配置1.6、启动程序入口实现 2、压测结果2.1、设置Jmeter线程组2.2、Jmeter聚合报告结果&#xff0c;支持11240/秒吞吐量2.3、Jmeter…

2022年电赛F题23年电赛D题-信号调制度测量装置说明中提到带通采样定律。

2022年电赛F题-信号调制度测量装置说明中提到带通采样定律。 23年电赛D题十分相似&#xff0c;但是22年载波达到了10M&#xff0c;根据奈奎斯特采样定理&#xff0c;我们知道想要分析出频谱不混叠的频谱图&#xff0c;采样率必须大于最大谐波的二倍。那么就意味着AD采样率要大…

2023年图灵奖揭晓,你怎么看?

Avi Wigderson——理论计算机科学的先锋&#xff0c;荣获2023年图灵奖 在科技界&#xff0c;图灵奖堪称与诺贝尔奖齐名的崇高荣誉&#xff0c;它每年授予对计算机行业的贡献达到重大突破的个人或团队。今年&#xff0c;这一声誉卓著的奖项被授予了普林斯顿大学的数学教授 Avi …

【攻防世界】lottery

弱比较代码审计 本题已提供源码&#xff0c;如果没提供&#xff0c;输入/robots.txt&#xff0c;发现/.git function buy($req){require_registered();require_min_money(2);$money $_SESSION[money];//接受用户原有money$numbers $req[numbers];//接受输入的数字$win_num…

面试八股——JVM★

类加载 类加载器的定义 类加载器的类别 类装载的执行过程 类的装载过程&#xff1a; 加载&#xff1a; 验证&#xff1a; 准备&#xff1a; 这里设置初始值并不是传统意义的设置初始值&#xff08;那个过程在初始化阶段&#xff09;。 解析&#xff1a; 初始化&#xff1a; …