Linux(多进程与多线程)

目录

1、进程与线程概念

1.1 进程

1.2 线程

1.3 进程与线程区别

2、多进程

2.1多进程概念

2.2 进程相关API

2.3 多进程编程

3、多线程

3.1 多线程概念

3.2 多线程相关API

3.3 多线程编程


1、进程与线程概念

1.1 进程

在计算机科学中,进程是正在执行中的程序的实例。一个进程包括程序的代码、数据、执行上下文和操作系统分配的资源。进程是操作系统中的最小执行单位,操作系统通过管理和调度进程来实现多任务处理。

以下是关于进程的一些关键概念:

  1. 程序 vs. 进程

    • 程序(Program):是一个静态的代码文件,包含了计算机指令。程序本身并没有在计算机上执行,而只是一组指令的集合。
    • 进程(Process):是程序在计算机上实际运行的实例。进程拥有自己的内存空间、寄存器、执行状态等。
  2. 进程特点

    • 独立性:每个进程都是独立运行的实体,不受其他进程的影响。
    • 并发性:多个进程可以同时执行,操作系统通过时间分片等机制实现并发。
    • 动态性:进程可以创建、运行和结束,具有生命周期。
  3. 进程状态

    • 就绪(Ready):进程已准备好执行,等待分配处理器资源。
    • 运行(Running):进程正在执行指令。
    • 阻塞(Blocked):进程等待某个事件(如输入输出完成)发生。
    • 终止(Terminated):进程执行完毕或被终止。
  4. 进程间通信: 进程可能需要相互通信和协作。常用的进程间通信方式包括管道、信号、共享内存、消息队列和套接字等。

  5. 进程调度: 操作系统负责管理和调度进程的执行。调度算法决定了哪个进程将获得处理器资源,并控制进程之间的切换。

  6. 进程控制块(PCB): PCB 是操作系统用于管理和描述进程的数据结构,包含了进程的状态、程序计数器、寄存器值、内存指针等信息。

进程是操作系统的基础概念,操作系统通过对进程的管理和调度,实现了计算机的多任务处理和资源共享。

1.2 线程

线程(Thread)是操作系统中最小的调度单位,它是进程的一个执行流程,是在进程内部进行调度和执行的基本单元。线程在同一进程内共享该进程的内存空间和资源,但每个线程拥有自己的栈空间和寄存器状态。

以下是关于线程的一些关键概念:

  1. 线程特点

    • 线程是在进程内部创建和管理的。一个进程可以包含多个线程,这些线程共享进程的资源。
    • 线程之间的切换开销较小,因为它们共享同一进程的内存空间和上下文。
    • 线程的创建和销毁通常比进程更快,因为线程共享进程的资源,不需要为每个线程都创建独立的资源。
    • 线程可以用于实现并发执行,提高系统的响应性和资源利用率。
  2. 线程与进程的关系

    • 一个进程可以包含多个线程,这些线程共享进程的代码、数据和资源。
    • 多个线程在同一进程内运行,它们之间可以进行通信和同步。
    • 多个进程则是相互独立的,拥有各自独立的内存空间和资源。
  3. 线程调度: 操作系统负责管理和调度线程的执行。不同的线程调度算法决定了哪个线程将获得处理器资源。

  4. 线程同步: 在多线程编程中,线程之间可能会互相干扰或冲突。线程同步机制,如互斥锁、信号量和条件变量,用于协调线程之间的操作,以确保数据一致性和正确性。

  5. 用户级线程和内核级线程

    • 用户级线程:线程的创建、调度和管理完全由用户程序控制,操作系统对线程无感知。
    • 内核级线程:线程的创建、调度和管理由操作系统控制,操作系统直接管理线程。

线程是操作系统中的基本调度单位,适用于需要并发执行的任务。通过多线程编程,可以充分利用多核处理器的能力,提高程序的性能和响应性。但同时,多线程编程也需要考虑到线程安全和同步的问题。

1.3 进程与线程区别

  1. 资源分配: 进程有独立的资源(内存、文件句柄等),而线程共享所属进程的资源。
  2. 切换开销: 进程之间的切换开销较大,线程之间切换开销较小。
  3. 隔离性: 进程之间相互隔离,一个进程的错误不会影响其他进程;线程共享内存,一个线程的错误可能会影响其他线程。
  4. 通信与同步: 进程通信较复杂,线程之间共享内存,通信和同步更方便但也更容易出错。

通常来说,多线程编程更轻量,可以更好地利用多核处理器,但需要更仔细地处理并发访问共享资源的问题。多进程编程相对来说更安全,但开销较大。选择使用进程还是线程取决于你的应用需求和对多任务处理的优先级。

2、多进程

2.1多进程概念

多个独立的进程在不同的地址空间中运行,相对安全但开销较大。

多进程编程是一种并发编程的方式,它利用操作系统的多进程能力来实现多个任务的并行执行。在多进程编程中,每个任务被封装为一个独立的进程,它们在不同的内存空间中运行,相互之间相对独立。这种方法可以有效利用多核处理器,提高程序的性能和响应性。

2.2 进程相关API

  1. fork() 函数:

    • 作用:创建一个新的子进程,子进程是父进程的副本,执行相同的程序代码。
    • 返回值:在父进程中,返回子进程的 PID;在子进程中,返回 0;如果失败,返回 -1。
    • 头文件:<unistd.h>
  2. exec 函数族(如 execl, execv, execle, execve 等):

    • 作用:用于在当前进程中加载并执行一个新的程序。
    • 使用不同的函数名和参数,支持不同的参数传递方式。
    • 返回值:只在出错时返回 -1,成功执行后不会返回。
  3. wait()waitpid() 函数

    • 作用:等待子进程结束,以获取子进程的退出状态。
    • wait() 阻塞调用进程,直到任意子进程退出。
    • waitpid() 允许指定要等待的子进程的 PID,可以非阻塞等待。
    • 返回值:退出的子进程 PID 或 -1(出错时)。
    • 头文件:<sys/wait.h>
  4. exit() 函数

    • 作用:终止调用进程,并返回一个状态码给父进程。
    • 参数:传递给父进程的状态码。
    • 没有返回值,直接终止进程。
  5. getpid() 函数:

    • 作用:获取当前进程的 PID(进程标识符)。
    • 返回值:当前进程的 PID。
    • 头文件:<unistd.h>
  6. getppid() 函数:

    • 作用:获取当前进程的父进程的 PID。
    • 返回值:父进程的 PID。
    • 头文件:<unistd.h>
  7. kill() 函数:

    • 作用:向指定进程发送信号。
    • 参数:目标进程的 PID 和信号编号。
    • 返回值:成功返回 0,失败返回 -1。
  8. getuid()getgid() 函数:

    • 作用:获取当前进程的用户 ID 和组 ID。
    • 返回值:用户 ID 和组 ID。
    • 头文件:<unistd.h>
  9. setuid()setgid() 函数:

    • 作用:设置当前进程的用户 ID 和组 ID。
    • 参数:要设置的用户 ID 和组 ID。
    • 返回值:成功返回 0,失败返回 -1。
  10. sleep() 函数:

    • 作用:让当前进程休眠一段指定的时间。
    • 参数:休眠时间(秒)。
    • 返回值:休眠完毕后返回剩余休眠时间(0 表示完整休眠,-1 表示休眠被中断)。

2.3 多进程编程

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h> // 包含用于等待子进程的头文件int main() {// 创建第一个子进程// 在父进程中,fork() 函数返回子进程的 PID,而在子进程中,fork() 返回 0。pid_t child1_pid = fork();if (child1_pid == -1) {// fork() 失败时返回 -1,输出错误信息并退出程序perror("Error creating child process");return 1;}if (child1_pid == 0) {// 子进程 1 逻辑printf("Child 1: My PID is %d\n", getpid());// 子进程 1 执行完毕return 0;}// 创建第二个子进程pid_t child2_pid = fork();if (child2_pid == -1) {// fork() 失败时返回 -1,输出错误信息并退出程序perror("Error creating child process");return 1;}if (child2_pid == 0) {// 子进程 2 逻辑printf("Child 2: My PID is %d\n", getpid());// 子进程 2 执行完毕return 0;}// 父进程逻辑printf("Parent: My PID is %d\n", getpid());printf("Parent: Child 1 PID is %d, Child 2 PID is %d\n", child1_pid, child2_pid);// 等待两个子进程执行完毕wait(NULL); // 等待第一个子进程wait(NULL); // 等待第二个子进程return 0;
}

运行结果

3、多线程

3.1 多线程概念

同一进程内的多个线程共享同一地址空间,更轻量但需要注意同步和共享数据。多线程编程可以提高程序的并发性和效率。然而,多线程编程需要注意处理并发访问共享资源的问题,如线程安全和竞态条件。

多线程编程是在同一个进程内创建和管理多个线程,使得这些线程可以并发执行不同的任务。每个线程共享进程的内存空间和资源,但每个线程有自己的栈空间和执行上下文。

3.2 多线程相关API

  1. pthread_create() 函数:

    • 作用:创建一个新线程。
    • 参数:新线程的引用、线程属性、线程函数和参数。
    • 返回值:成功创建线程时返回 0,否则返回错误码。
    • 头文件:<pthread.h>
  2. pthread_join() 函数:

    • 作用:等待一个线程终止,并获取它的退出状态。
    • 参数:要等待的线程的引用、线程退出状态的指针。
    • 返回值:成功返回 0,否则返回错误码。
    • 头文件:<pthread.h>
  3. pthread_exit() 函数:

    • 作用:终止当前线程,可指定线程退出状态。
    • 参数:线程退出状态。
    • 没有返回值,直接终止线程。
    • 头文件:<pthread.h>
  4. pthread_self() 函数:

    • 作用:获取当前线程的线程 ID。
    • 返回值:当前线程的线程 ID。
    • 头文件:<pthread.h>
  5. pthread_mutex_init() 函数:

    • 作用:初始化互斥锁。
    • 参数:互斥锁引用和互斥锁属性(可为 NULL)。
    • 返回值:成功返回 0,否则返回错误码。
    • 头文件:<pthread.h>
  6. pthread_mutex_lock()pthread_mutex_unlock() 函数:

    • 作用:锁定和解锁互斥锁。
    • 参数:互斥锁引用。
    • 返回值:成功返回 0,否则返回错误码。
    • 头文件:<pthread.h>
  7. pthread_mutex_destroy() 函数:

    • 作用:销毁互斥锁。
    • 参数:互斥锁引用。
    • 返回值:成功返回 0,否则返回错误码。
    • 头文件:<pthread.h>
  8. pthread_cond_init() 函数:

    • 作用:初始化条件变量。
    • 参数:条件变量引用和条件变量属性(可为 NULL)。
    • 返回值:成功返回 0,否则返回错误码。
    • 头文件:<pthread.h>
  9. pthread_cond_wait()pthread_cond_signal() 函数:

    • 作用:等待和唤醒条件变量。
    • 参数:条件变量引用和互斥锁引用。
    • 返回值:成功返回 0,否则返回错误码。
    • 头文件:<pthread.h>
  10. pthread_cond_destroy() 函数:

    • 作用:销毁条件变量。
    • 参数:条件变量引用。
    • 返回值:成功返回 0,否则返回错误码。
    • 头文件:<pthread.h>

3.3 多线程编程

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>#define NUM_THREADS 4 //创建线程数量// 共享资源
int shared_counter = 0;
pthread_mutex_t mutex; // 互斥锁// 增加计数器的函数,多个线程会同时调用这个函数
void* increment_counter(void* arg) {for (int i = 0; i < 100000; ++i) {pthread_mutex_lock(&mutex); // 加锁,开始临界区shared_counter++; // 对共享资源进行操作pthread_mutex_unlock(&mutex); // 解锁,结束临界区}return NULL;
}int main() {pthread_t threads[NUM_THREADS]; // 存储线程的数组pthread_mutex_init(&mutex, NULL); // 初始化互斥锁// 创建多个线程for (int i = 0; i < NUM_THREADS; ++i) {pthread_create(&threads[i], NULL, increment_counter, NULL);}// 等待所有线程执行完毕for (int i = 0; i < NUM_THREADS; ++i) {pthread_join(threads[i], NULL);}pthread_mutex_destroy(&mutex); // 销毁互斥锁printf("Final counter value: %d\n", shared_counter);return 0;
}

运行结果(为啥输出了三次?

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

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

相关文章

不同版本.net引用同一个项目

项目文件.csproj文件内容如下&#xff1a; 重点是&#xff1a;不能有其他的 netstandard2;net40;net45;net46;net6 <Project Sdk"Microsoft.NET.Sdk"><PropertyGroup><TargetFrameworks>netstandard2;net40;net45;net46;net6</TargetFrame…

2023.08.27 学习周报

文章目录 摘要文献阅读1.题目2.重点3.引言4.方法5.实验结果6.结论 深度学习Majorization-Minimization算法1.基本思想2.要求3.示意图 总结 摘要 This week, I read a computer science on the prediction of atmospheric pollutants in urban environments based on coupled d…

Spring MVC详解

文章目录 一、SpringMVC1.1 引言1.2 MVC架构1.2.1 概念1.2.2 好处 二、开发流程2.1 导入依赖2.2 配置核心(前端)控制器2.3 后端控制器2.4 配置文件2.5 访问 三、接收请求参数3.1 基本类型参数3.2 实体收参【重点】3.3 数组收参3.4 集合收参 【了解】3.5 路径参数3.6 中文乱码 四…

postgresql 条件表达式

postgresql 条件表达式 简单CASE表达式搜索CASE表达式缩写函数nullif函数示例 coalesce函数 总结 简单CASE表达式 语法如下 case 表达式when 值1 then 结果1when 值2 then 结果2else 默认值 end;select e.first_name , e.last_name , case e.department_id when 90 then 管…

搭建web网站

1.基于域名www.openlab.com可以访问网站内容为welcome to openlab!!! (1).安装所需软件HTTPD、mod_ssl [rootserver ~]# yum install httpd mod_ssl -y 添加域名映射&#xff1a;vim /etc/hosts (2)创建网站目录及网页&#xff0c;修改主配置文件新建openlab目录网站 配置文…

java.lang.NullPointerException: null 不显示异常栈

一、问题 排查线上问题时&#xff0c;发现日志中异常输出的地方&#xff0c;仅有一行java.lang.NullPointerException: null&#xff0c;截图如下。 丢失了具体的异常栈&#xff0c;导致无法定位是哪行代码抛出了异常。 这里排除日志用法的问题&#xff0c;以前是正常能输出异…

Android BatteryManager的使用及BatteryService源码分析

当需要监控系统电量时&#xff0c;用 BatteryManager 来实现。 参考官网 监控电池电量和充电状态 获取电池信息 通过监听 Intent.ACTION_BATTERY_CHANGED 广播实现&#xff0c;在广播接收器中获取电池信息。 这是个粘性广播&#xff0c;即使过了广播发出的时间点后再注册广…

大数据Flink(六十六):Flink的重要概念和小结

文章目录 Flink的重要概念和小结 一、​​​​​​​​​​​​​​数据流图(Dataflow Graph)

尝试自主打造一个有限状态机(二)

前言 上一篇文章我们从理论角度去探索了状态机的定义、组成、作用以及设计&#xff0c;对状态机有了一个基本的认识&#xff0c;这么做有利于我们更好地去分析基于实际应用的状态机&#xff0c;以及在自主设计状态机时也能更加地有条不紊。本篇文章将从状态机的实际应用出发&am…

wazuh环境配置及案例复现

文章目录 wazuh环境配置及案例复现wazuh环境配置 案例复现 wazuh环境配置及案例复现 wazuh环境配置 进入官网下载ova软件 https://documentation.wazuh.com/current/deployment-options/virtual-machine/virtual-machine.html 打开下载的ova&#xff0c;密码和用户名会显示…

sql developer 连不上oracle数据库 报错 ORA-01031: insufficient privileges

sql developer 连不上oracle数据库 报错 ORA-01031: insufficient privileges 1、问题描述2、问题原因3、解决方法4、sql developer 连接oracle 成功 1、问题描述 使用sys账户以SYSDBA角色登录失败 报错 ORA-01031: insufficient privileges 2、问题原因 因为没有给sys账户分…

【Go 基础篇】Go语言中的defer关键字:延迟执行与资源管理

介绍 在Go语言中&#xff0c;defer 是一种用于延迟执行函数调用的关键字。它提供了一种简洁而强大的方式&#xff0c;用于在函数返回之前执行一些必要的清理操作或者释放资源。defer 的灵活性和易用性使得它在Go语言中广泛应用于资源管理、错误处理和代码结构优化等方面。&…

2023年高教社杯数学建模思路 - 复盘:人力资源安排的最优化模型

文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 描述 …

手把手教你用 ANSYS workbench

ANSYS Workbench ANSYS Workbench是一款基于有限元分析&#xff08;FEA&#xff09;的工程仿真软件。其基本概念包括&#xff1a; 工作区&#xff08;Workspace&#xff09;&#xff1a;工程仿真模块都在此区域内&#xff0c;包括几何建模、网格划分、边界条件设置、分析求解等…

Ubuntu-Server 22.04安装详细过程-图文版

一.下载Ubuntu Server镜像&#xff0c;官方地址下载即可 https://ubuntu.com/download/server 乌班图镜像网址&#xff0c;点击下载即可 二.安装乌班图镜像&#xff0c;最好自己准备u盘在ISO软件内制作完成 1.选择 Install Ubuntu Server 2.选择安装语言为英语 3.安装程序更新选…

C#,《小白学程序》第二课:数组与排序

1 文本格式 /// <summary> /// 《小白学程序》第二课&#xff1a;数组与排序 /// </summary> /// <param name"sender"></param> /// <param name"e"></param> private void button2_Click(object sender, EventArgs …

Vue3(开发h5适配)

在开发移动端的时候需要适配各种机型&#xff0c;有大的&#xff0c;有小的&#xff0c;我们需要一套代码&#xff0c;在不同的分辨率适应各种机型。 因此我们需要设置meta标签 <meta name"viewport" content"widthdevice-width, initial-scale1.0">…

SD 总线引脚介绍

参考 https://www.cnblogs.com/justin-y-lin/p/12259851.html SD卡与TF卡的引脚定义 - 360文档中心

java+springboot+mysql医院预约挂号管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的医院预约挂号管理系统&#xff0c;系统包含超级管理员、管理员、医生、患者角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;管理员管理&#xff1b;用户管理&#xff1b;科室管理&#xff1b;床位管理&…

Linux系统编程之文件编程常用API回顾和文件编程一般步骤

目录 1.打开文件 2.创建文件 3.写入文件 4.读取文件 5.光标定位 6.关闭文件 7.文件编程一般步骤 Linux系统提供了一些常用API如&#xff1a; 打开/创建 open/creat 读写 write /read 光标定位 Iseek 关闭 close 1.打开文件 参数说明 Pathname:要打开的文件名 (含路径&…