并发程序设计

news2025/1/21 10:16:47

一、进程的创建和回收

(一)进程的概念

1、进程!=程序

程序是静态的,而进程是动态的,进程是程序执行的一种状态。

2、进程和程序的区别

1)进程控制块中包含进程的属性

2)程序在磁盘里面,堆栈都是在内存中,程序运行起来都在内存中

3)进程的运行在内存(RAM)中,手机内存指的是运行内存64G,电脑内存指的是硬盘(ROM)

4)初始化的全局变量在数据段,没有初始化的全局变量放在BSS中

代码段存放可执行文件,机器码

5) static声明的变量不在栈中,和全局变量放在一起

栈:参数,返回值,局部变量

堆:malloc

6)一个进程会被分为不同的区域

7)进程控制块(pcb)

PID、进程用户、进程状态、优先级、文件描述符表

3、进程的类型

1)交互进程:最常用的进程,在前台运行且在shell下可以控制

2)批处理进程:提交到作业队列以便顺序执行

3)守护进程:一直在后台运行,不能用shell命令控制

4、进程的状态

(二)进程常用的命令

1、查看进程信息

1)ps当前状态下的进程

2)ps -e当前状态下Linux所有的进程

3)ps -elf Linux下进程的详细信息

4)进程状态

5)进程标志

6)ps下的目录含义

PID:进程ID

CMD:进程的名称

NI:进程优先级

PRI:进程优先级

SZ:占用内存

C:占用的CPU利用率

7)ps -elf|grep PID

查看某个进程

2、top实时查看进程信息

1)翻页shift+'<'(前翻页)或'>'(后翻页)

2)top -p PID查看某个进程

3)ctrl+c退出

3、/proc查看进程的某个目录

4、nice命令:打开一个进程,设置优先级

越nice优先级越低

 1)一般nice只能调高

2)只有root才能设置为负值

4)renice改变优先级

5、后台进程

6、前台和后台的区别

./test在前台运行:

正常情况下ctrl+C可以结束进程,下次该进程对应的代码还是前台运行

6、ctrl+Z结束前台运行转为后台

ctrl+Z:此时程序进入停止状态

7、jobs查看后台进程,这时进程已经在后台

8、bg将挂起的进程在后台运行

9、./test &也可使后台进程运行 

 10、fg将后台进程重新挂到前台运行

fg+序号进程又重新挂到前台

*(三)创建子进程

1、子进程的概念

在Linux下除了0号进程,其他的进程都是由别人创建的

2、创建子进程

让我们的进程创建子进程

1)代码

子进程B的代码和A的代码相同

但子进程B只执行程序中fork函数之后的代码

2)打印结果

父进程子进程分别打印

3)如何让父子进程分别执行

(四)父子进程

1、子进程只执行fork之后的代码

2、父子进程执行顺序是操作系统决定的

 3、父子进程的关系

(五)结束进程

1、若父进程先结束,被init进程收养,子进程变成后台进程

1)分别对父子进程加一个sleep

父子进程随机运行

子父进程ID

kill掉父进程

子进程的父进程变成了2107,也就是init进程

子进程变成后台进程

2、如果子进程先结束,父进程没有来得及回收,子进程变成僵尸进程

kill掉父进程

此时kill掉父进程,子进程消失

(五)子进程进阶

1、孙进程

子进程也进行了for循环 

解决办法:子进程执行结束break

(六)进程的退出

1、exit会刷新缓冲流-库函数-<stdlib.h>

2、_exit不会刷新缓冲流-系统调用-<unistd.h>

3、main函数return会隐式调用exit

两个结果相同,其他函数return只是返回上一级

4、exit和return两个结果相同

4、_exit:没有刷新流缓冲区

(六)进程的回收

*1、wait-回收并查看子进程的情况

2、status和结束返回2的进程不同

3、16进制打印200不是2

4、用宏来取得进程的返回值

5、父进程对子进程的回收

1)不回收

2)回收

僵尸进程:子进程结束,但是没有被父进程回收

*(二)waitpid进程回收

1、waitpid

2、指定pid

3、WNOHANG不阻塞,直接执行,如果当前子进程还未结束,则会出错

出错:

修正:休眠2秒,等子进程结束

二、exec函数族

(一)exec函数族的执行过程

1、父进程的父进程是shell

2、函数族-有很多个函数组成

3、通过调用exec函数族执行某个程序

4、调用exec函数族进程当前内容被指定的程序替换

5、相当于父子进程执行不同程序

(二)execl函数和execlp函数

1、execl-需要写全部路径

相当于命令“ls -a -l”

2、execlp-不需要写全部路径

执行效果和execl相同

(三)execv函数和execvp函数

1、execv-全部路径-将命令定义成数组

2、execvp-不需要全部路径-数组

(四)system函数

1、system的实现

*(五)exec函数族特点

1、exec函数族-进程当前内容被指定内容替换,exec函数以后的程序没有被执行

2、第0个参数不使用但是要写

3、父子进程执行不同程序

三、GDB调试

(一)GDB调试多进程程序

1、想要用GDB调试,编译加-g

gcc -g -o 编译生成的名字 文件名

2、进入gdb模式命令

gdb 可执行文件

3、quit 退出

4、start开始调试

5、n进入下一步

6、默认跟踪父进程

1)set follow-

显示可以跟踪的进程

2)set follow-fork-mode

可以继续选择跟踪父子进程

3)跟踪孩子

set follow-fork-mode child

4)同时调试父子进程

调试子进程,同时可以切换父进程

5)切换调试的进程

info inferiors查看可以运行的进程

6)切换跟踪进程

inferior 序号

7、调试多进程

四、守护进程

(一)守护进程的概念

1、守护进程是后台进程,始终是后台运行

2、守护进程独立于终端

3、进程组-会话-控制终端

与控制终端连接的进程就是控制进程。

1)进程组

2)会话

一个终端界面可以理解成一个会话

3)控制终端-就是终端

4、守护进程

5、守护进程是孤儿进程

6、守护进程的创建

1)创建子进程,然后令子进程变成孤儿进程,被init收养,变成后台进程

此时子进程已经被init收养

2)创建会话-setsid

称为新的会话组长

自己当家做主人了 

3)改变工作目录-不被之前的父进程目录局限

4)重设掩码-创建文件权限(不是必须的)

5)关闭打开的文件描述符 

关闭文件描述符后,不会在打印到屏幕

守护进程不能在屏幕上打印东西,不能接收键盘的输入

6)nohup ./test.c &:将前台进程转为后台进程

没有写守护进程变成后台的方法

守护进程的实现

五、线程的创建和参数传递

(一)线程的基本特点

1、线程共享相同的地址空间和全局变量

2、线程是在windows下创建的,被Linux引用,Linux不分线程和进程

3、线程的特点

4、线程共享资源

常用:静态数据、文件描述符、工作目录

5、  线程的私有资源

常用:错误号、堆栈

(二)使用pthread库函数创建线程

1、pthread线程库

线程不是通过Linux内核实现,而是由线程库来实现。

2、创建线程

(三)常见编译错误及处理方法

链接错误线程编译要加上-lpthread

(四)线程的运行特点

1、线程创建需要时间,如果主进程退出,线程不能得到执行,马上退出

主进程退出,创建的线程也会退出 

2、sleep 1秒,线程创建成功

(五)线程id的获取

1、线程的退出

2、pthread_exit()函数-常用于清理线程

3、打印tid

1)主函数中,直接获取

2)pthread_self()函数-函数中获得自己的id

3)打印pid

**(六)线程的参数传递

1、通过地址传递参数,注意类型转换

void定义下的arg是任意类型,直接转换成Int类型

2、也可以值传递-可能会报警,需要程序员自己保证数据长度正确

3、建立多个线程并分别向其传参

(七)段错误的原因及处理方法

六、线程的回收及内存演示

(一)pthread_join与pthread_exit

相当于进程中的wait函数

1、pthread_join主函数对线程的回收-阻塞函数,线程没有回收则等待

pthread_join在主函数中,接收线程结束的返回值

2、pthread_exit 线程结束函数

(二)pthread_join函数特点

1、一个缺点,如果是单线程回收方便,循环创建多线程,如果最开始的线程没有结束,pthread_join也会阻塞

(三)线程分离pthread_detach

1、线程主动与主控线程断开关系,自己可以回收,不需要pthread_join

2、pthread_detach使用

在主函数中:

不阻塞

在线程函数中:

3、线程属性分离

4、回收线程的三种方式

1)pthread_join(局限):阻塞,多线程阻塞
2)pthread_detach
3)创建线程时分离属性

(四)线程回收内存演示

查看内存命令: top -p 进程号

线程回收前

等待线程回收后

七、线程的取消和清理

(一)pthread_cancel与线程取消点

1、查看线程-L大写

ps -eLf |grep detach

2、杀掉线程

1)必须有取消点-阻塞

2)gdb命令:bt-打印调用栈

(二)GDB调试段错误

(三)pthread_testcancel手动设置取消点

1、线程取消需要取消点-阻塞

2、如果不确定有没有取消点,可以手动设置一个取消点

(四)pthread_setcancelstate设置取消属性

1、取消取消点

2、恢复其他地方取消点

3、主函数中的sleep

(五)线程取消pthreas_setcanceltype

(六)线程清理

1、如果线程申请了一块内存,但线程因为阻塞被取消,则会造成内存泄露

2、线程清理是在线程异常退出之后,进行清理

3、线程的清理函数本质上是宏定义,必须成对使用

push-pop

4、

return可以结束线程,但是不能出发清理函数

5、可以cancel自己

两种情况:

1)到取消点取消,取消点之前可以取消

2)立即取消

八、**互斥锁/读写锁/死锁

一、互斥锁的概念和使用

(一)临界资源

1、临界资源是只允许一个资源访问的任务,互斥资源

2、外设、磁盘都是临界资源

3、临界区是访问临界资源的代码

(二)互斥机制

1、动态初始化创建

2、静态方式创建

3、锁的销毁

4、互斥锁的使用

5、申请锁

1)两个函数的区别

6、释放锁

*(三)互斥锁

1、创建两个线程,打印字符到文件中

主函数:

1.txt:两个线程随机打印,乱序

2、使用静态方式定义互斥锁

1)初始化互斥锁

2)添加互斥锁

3)添加了互斥锁之后的1.txt

4)如果线程执行多个任务,例如多个文件的写操作,需要定义多个互斥锁

二、读写锁概念和使用

1、读写锁-提高线程的读写速度-可同时读

2、防止读的时候有线程写入

3、同一时刻只有一个线程可以获得写锁,同一时刻可以有多个线程获得读锁

4、代码

1)在主函数中定义读写锁

2)结构体变量声明

3)加锁

4)结果与互斥锁相同

结论:读写锁与互斥锁结果相近

5、读写锁-只读

读写锁比互斥锁好的地方是,读写锁可以允许写的时候读

三、死锁的避免

1、死锁的概念

2、死锁都是在一把锁的情况下

3、代码

1)设置两把锁,两个线程同时调用两个资源

2)解决办法

延长休眠时间

1、使用一把锁,锁越少越好

2、获得1,2的先后顺序相同

九、条件变量的使用及注意事项

一、条件变量基本使用
1、线程等待某个资源时,休眠,提高运行效率
2、条件变量函数
1)等待资源
2)信号
3、步骤
1)初始化条件变量
2)定义互斥量
3)生产者
4)消费者
2、代码
1)主函数
2)生产者
3)消费者
4)准备条件
结果:
3、一定要和互斥锁使用
二、条件变量使用注意事项

十、线程尺及gdb调试多线程

一、线程池的概念

1、一般线程创建使用完都会被回收

2、线程的创建和销毁>线程的执行,时间不划算

3、线程池的结构

1)任务队列

2)线程池工作线程

二、线程池的实现

三、线程的GDB调试

1、主函数

2、设置断点 b

3、run运行程序

4、info thread查看线程

5、切换线程

6、下一步next

7、执行完一个线程后再次查看,线程消失

8、

9、设置线程锁

设置之后,除了选定的线程,其他不执行

10、切换到第3个,第6行断电

十一、有名管道和无名管道

一、无名管道基础

(一)进程间通信方式

**(面试题)1、进程间通信的方式

1)无名管道-亲缘进程

2)有名管道

*3)信号

4)共享内存

5)套接字-网络-进程间通信

进程-进程/主机-主机

开销最大

6)古老

(二)无名管道的特点

1、概念

相当于共享内存,通过管道传递消息

2、特点

1)只能父子或兄弟

2)单工通讯-固定读端和写端

2)创建两个文件描述符

3、无名管道的创建

单工通信-每个进程fd[0]和fd[1]只能用一个

(三)无名管道的创建

父子进程间的通信:

只有读操作之后才能打印buf

二、无名管道进阶

1、父进程创建了无名管道

2、子进程进程描述符相同

3、关闭管道

父子进程都可以关闭读写管道,无论这一段是读还是写

4、在同一个进程自己读和自己写是进行不了的

子进程之间相互通信:

5、管道可以用于大于两个进程的共享

6、可以两个子进程读/写,父进程写/读

7、无名管道的读写特性

管道大小是64K

三、有名管道概念和使用

(一)有名管道的特点

1、通过文件系统,但是文件不是放在磁盘,放在内存中,通过文件IO

2、有名管道的特点

(二)有名管道的创建

1、有名管道的创建

路径不能是Linux和wins共享目录

2、直接创建在根目录下

(三)有名管道的读写

1、写进程代码:

2、读进程代码:

读写结果:

四、有名管道的注意事项

1、不能使用读写方式打开文件

2、文件可以创建在根目录下,但是不能创建在共享目录下

3、默认情况下只写O_RDWR和只读O_RDONLY参数是阻塞的,加了第二个参数,不会阻塞,没有内容可读,直接退出

一个参数阻塞:

两个参数:

读文件:没有内容直接报错

有内容读内容

写文件:打开失败

注意事项

1、BSS存放没有初始化的全局变量。

2、static声明的变量不在栈中,和全局变量放在一起。

3、栈:参数,返回值,局部变量

堆:malloc

4、ps -elf 查看Linux下进程的详细信息

ps -elf|grep PID查看某个进程

top动态查看Linux下进程的实时信息

top -p PID查看某个进程

/proc查看进程的某个目录

5、子进程和父进程执行的代码相同,但子进程只执行程序中fork函数之后的代码(也就是子进程创建后的代码)。

6、fork函数创建子进程成功后,父进程返回子进程的进程号(进程号大于0),子进程返回0。

7、若父进程先结束,子进程变成孤儿进程,被init进程收养变成孤儿进程;若子进程先结束,父进程没有及时回收,子进程变为僵尸进程。

8、子进程通过exit/_exit/return返回,父进程通过wait(&status)回收子进程,wait有返回值。

9、exec函数使得进程当前内容被指定内容替换,exec函数以后的程序没有被执行自己,子进程调用exec函数族,父进程不受影响。

10、gdb调试命令:gcc -g -o 编译生成的名字 文件名

11、关闭文件描述符1,2,3,守护进程不能在屏幕上打印东西,不能接收键盘的输入。

12、内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数,打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。文件描述符0, 1, 2 默认为 stdin stdout stderr。

13、pthread_join在主函数中,接收线程结束的返回值。pthread_exit 线程结束函数,在线程内,返回值可以是一句提示语句。
14、

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

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

相关文章

【TA 挖坑05】效果:空间切换 场景切换

不知不觉挖坑都第5篇了&#xff0c;&#xff0c;&#xff0c;&#xff0c;再不填坑就成挖坑专业户拉&#xff01;&#xff01;&#xff01; 记录一下想实现的效果&#xff0c;实际上之前尝试从shader层面做能看得过去的&#xff0c;但是应用起来很拉跨&#xff0c;必须场景所有…

多模态GPT-V出世!36种场景分析ChatGPT Vision能力,LMM将全面替代大语言模型? | 京东云技术团队

LMM将会全面替代大语言模型&#xff1f;人工智能新里程碑GPT-V美国预先公测&#xff0c;医疗领域/OCR实践166页GPT-V试用报告首发解读 ChatGPT Vision&#xff0c;亦被广泛称为GPT-V或GPT-4V&#xff0c;代表了人工智能技术的新里程碑。作为LMM (Large Multimodal Model) 的代表…

Redis:2023年的必修课,不学就要被市场淘汰

一、同样是缓存&#xff0c;用map不行吗&#xff1f; Redis可以存储几十个G的数据&#xff0c;Map行吗&#xff1f;Redis的缓存可以进行本地持久化&#xff0c;Map行吗&#xff1f;Redis可以作为分布式缓存&#xff0c;Map只能在同一个JVM中进行缓存&#xff1b;Redis支持每秒…

Redux 学习笔记

在使用 React Redux 前&#xff0c;我们首先了解一下 Redux 的一些基础知识。 Redux 是 JavaScript 应用程序中用于状态管理的容器。它不依赖于任何框架&#xff0c;可以与任何 UI 库和框架一起使用。在应用程序中使用 Redux 时&#xff0c;Redux 是以可预测的方式管理状态。 …

鸿蒙HarmonyOS应用开发:扫描仪文件扫描

华为鸿蒙HarmonyOS已经发展到4.0&#xff0c;使用ArkTS作为开发语言。这篇文章结合Dynamsoft Service开发一个简单的鸿蒙应用&#xff0c;用来获取办公室里连接PC的扫描仪(惠普&#xff0c;富士通&#xff0c;爱普生&#xff0c;等)&#xff0c;把文档扫描到手机里。 准备工作…

Python 3.12.0 Release 版本

本心、输入输出、结果 文章目录 Python 3.12.0 Release 版本前言与 Python 3.11 相比&#xff0c;Python 3.12 系列主要更新了哪些新的功能更灵活的 f 字符串解析&#xff0c;允许许多以前不允许的事情 &#xff08;PEP 701&#xff09;。支持 Python 代码中的缓冲区协议 &…

Unity实现方圆X范围随机生成怪物

using System.Collections; using System.Collections.Generic; using UnityEngine;public class CreatMonster : MonoBehaviour {// S这个脚本间隔一点时间生成怪物/*1.程序逻辑* 1. 设计一个计时器* 2.间隔一段时间3s执行一下 * */float SaveTime 0f;public GameObject …

【215. 数组中的第K个最大元素】

目录 一、题目描述二、算法原理三、代码实现 一、题目描述 二、算法原理 三、代码实现 class Solution { public:int getRandom(int left,int right,vector<int>& nums){return nums[rand()%(right-left1)left];}int qsort(int l,int r,vector<int>& nums…

已经有多人中招,不要被AI换脸技术骗了!

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

LinkedList 源码解析(JDK1.8)

目录 一. 前言 二. 常用方法 三. 源码解析 3.1. 属性和内部类 3.2. 构造函数 3.3. 添加元素 3.4. 获取元素 3.5. 删除元素 3.6. 迭代器 3.6.1. 头到尾方向的迭代 3.6.2. 尾到头方向的迭代 3.6.3. add() 插入元素 3.6.4. remove() 移除元素 一. 前言 LinkedList同时…

ATA-8202射频功率放大器参数指标及应用介绍

ATA-8202射频功率放大器简介 ATA-8202是一款射频功率放大器。其P1dB输出功率100W&#xff0c;饱和输出功率200W。增益数控可调&#xff0c;一键保存设置&#xff0c;提供了方便简洁的操作选择&#xff0c;可与主流的信号发生器配套使用&#xff0c;实现射频信号的完美放大。宽…

JavaScript 中的Hoisting是什么?

在JavaScript中,Hoisting(变量提升)是指在代码执行之前,JavaScript引擎将变量和函数的声明提升到当前作用域的顶部的行为。 具体来说,JavaScript引擎在执行代码之前会进行两个步骤:编译阶段和执行阶段。在编译阶段,JavaScript引擎会将变量声明和函数声明提升到当前作用…

智能井盖监测系统,增加城市管理便捷性

看起来小小的井盖&#xff0c;实际上折射的是一个城市&#xff0c;一个地区的发展状况。每一个城市的道路网络&#xff0c;决定了一个城市发展的缓慢程度&#xff0c;哪怕是其中的井盖&#xff0c;有着自己的职责&#xff0c;是城市生命线的不可缺少的组成部分。但是现如今传统…

Qt10-19

第一个界面的头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QMovie>//动态图片所用的类 #include<QMessageBox>//消息对话框类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget …

国产主控应用案例:汉王电子血压计-君正开发板

2023春季新品发布会上汉王科技发布柯氏音法电子血压计产品—汉王电子血压计&#xff0c;继嗅觉检测盒之后再次深度布局大健康领域。 不同于当前市面上使用示波法原理的电子血压计&#xff0c;汉王电子血压计采用血压测量金标准中的柯氏音法&#xff0c;由此引领一场电子血压计领…

出东方利中国!长城五星牵手国家宝藏,共谱丝路艺术华章

执笔 | 尼 奥 编辑 | 古利特 当中国葡萄酒与国家宝藏、非遗工艺灵魂碰撞&#xff0c;又将产生怎样的大国之美&#xff1f;长城五星艺术干红给出答案。 10月19日&#xff0c;长城五星艺术干红上市发布会在成都召开。会上&#xff0c;长城葡萄酒正式发布文化战略新品——“五…

“达观杯”智能文档版面分析赛题baseline已上线,欢迎下载报名!

由国内领先智能文本处理企业达观数据与上海市计算机学会联合举办的智能文档版面分析多模态数据处理算法竞赛正在火热报名阶段。开赛一周内&#xff0c;第七届“达观杯”已有来自国内外的近200名企业和高校算法精英参与到比赛中。作为本次赛题的出题方&#xff0c;为助力各位打榜…

taro使用defineConstants定义全局变量eslint报错该变量不存在

问题描述 在taro项目中使用defineConstants定义一些全局变量供业务代码中进行使用&#xff0c;全局变量声明config/index.js代码如下&#xff1a; module.exports {defineConstants: {LOGIN_URL: JSON.stringify(/baidu/login), },全局变量使用代码如下&#xff1a; /*** 跳…

高速DSP系统设计参考指南(四)DSP电源设计

&#xff08;四&#xff09;DSP电源设计 1.电源设计的重要性2.DSP电源架构考虑3.电源去耦技术3.1 一般经验法则解耦法3.2 解耦分析方法3.3 分析案例3.4 计算去耦电容值3.5 高频噪声隔离 1.电源设计的重要性 电源设计可能是高速 DSP 设计中控制噪声和辐射的整个过程中最具挑战性…

Affinity Photofor Mac/Windows:专业级图片编辑的终极选择

在今天的内容中&#xff0c;我们将要介绍一款备受赞誉的图片编辑软件——Affinity Photo。无论你是业余的摄影爱好者&#xff0c;还是专业的设计师&#xff0c;Affinity Photo都能为你提供丰富的编辑功能和出色的使用体验。 首先&#xff0c;让我们来简单了解一下Affinity Pho…