当前位置: 首页 > news >正文

操作系统实验——线程与进程

如果代码或文章中,有什么错误或疑惑,欢迎交流沟通哦~


## 进程与线程的区别 1. **各自定义**:

进程是操作系统进行资源分配和调度的一个独立单位,具有一定独立功能的程序关于某个数据集合的依次运行活动。

线程被称为轻量级的进程,是进程中的实体,是被操作系统独立调度和分派的基本单位。

  1. 内存

    进程每启动一个新的,就需要分配独立的内存空间,而线程是在同一个进程下,共享相同的内存空间,因此线程的启动和关闭以及切换的除存需要的系统开销都要比进程小。

  2. 通信方式:

    进程间需要使用进程间通信(IPC, Inter-Process Communication)的方式来进行通信,例如:**管道,信号,消息队列,共享内存,信号量等。**而同一进程中的线程共享相同的内存空间,所以线程之间可以直接访问同一进程内的全局变量,静态变量等数据,线程间通信比进程间通信要容易得多。

  3. 影响范围

    由于进程具有独立的内存空间,所以一个进程崩溃后,在保护模式下,不会对其他进程产生影响,但是一个线程崩溃后,会导致整个进程崩溃。

  4. 改变环境:

    每个独立的进程有一个完全独立的运行环境,改变自己的运行环境(如改变文件打开方式、改变信号处理方式等)不会影响其他进程。而线程则不同,一个线程改变其运行环境会影响到同在一个进程中的其它线程。

fork()

用fork( )创建进程必须的几个要点:

  • 有一段程序供该进程运行
  • 进程专用的系统堆栈空间
  • 进程控制块PCB,在linux中具体实现是task_struct
  • 独立的内存空间

如果没有自己独立的内存空间,就称为线程。

线程与进程的区别,在于线程没有独立的内存空间。

使用fork()来创建进程

//testFork.c
#include<stdio.h>
#include<unistd.h>
int main() 
{ int count=1;int child;
if(!(child=fork())) 
printf("This is son, his count is: %d. and his pid is: %d\n", ++count, getpid());
else printf("This is father, his count is: %d, his pid is: %d\n", count, getpid());
}显示结果:
This is son, his count is: 2. and his pid is: 302
This is father, his count is: 1, his pid is: 301

fork() 调用会创建一个新的进程,这个新的进程是当前进程的复制品,被称为子进程。
fork() 函数在父进程中返回新创建的子进程的进程ID,而在子进程中返回0。
也就是说,如果child = fork() 的值为0,则说明在子进程中,将执行
printf("This is son, his count is: %d. and his pid is: %d\n", ++count, getpid());语句。
否则说明在父进程中,将执行
printf("This is father, his count is: %d, his pid is: %d\n", count, getpid()); }语句。

这两行打印语句的区别在于,子进程的count值会加一,且父子进程的pid是不同的。

vfork()

  • 在Unix和类Unix系统中,vfork()是一种特殊的fork()。
  • vfork()创建的子进程可能与父进程共享内存,这意味着子进程可以修改父进程的内存空间,这与fork()是不同的。
  • 执行vfork()函数创建的进程,仍然是父进程和子进程的关系,有各自独立的进程ID,但在一些系统(如早期的Unix系统)中,vfork()创建的子进程和父进程共享同一地址空间,父进程在子进程结束执行或者调用exec系列函数之前停止执行。这一点与fork()存在明显的差异

使用vfork()创建子进程

//testVfork.c
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
int main( ) 
{  int count=1;  int child;printf("Before create son, the father's count is:%d\n", count);
if(!(child=vfork())){  printf("This is son, his pid is: %d and the count is: %d\n", getpid(), ++count);exit(0);   }else printf("After son, This is father, his pid is: %d and the count is: %d, 
and the child is: %d\n", getpid(), count, child);
}显示结果:
Before create son, the father's count is:1
This is son, his pid is: 4185 and the count is: 2
After son, This is father, his pid is: 4184 and the count is: 2, and the child is: 4185

注意这里有三个打印语句,其中两个打印语句是在父进程当中,
printf("Before create son, the father's count is:%d\n", count);printf("After son, This is father, his pid is: %d and the count is: %d, and the child is: %d\n", getpid(), count, child);这两个语句。
而子进程中的打印语句 printf("This is son, his pid is: %d and the count is: %d\n", getpid(), ++count);,将父子进程共享空间里的count++了,所以父进程后一条打印语句也会打印得到count=2

用vfork创造线程和父子进程的同步问题

在使用 vfork() 创建子进程后,父进程将会被挂起。父进程的执行只会在子进程调用 exit() 或者执行 execve() 开始新程序后才会继续。这是 vfork()fork() 的一个主要区别。

//testVfork.c
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
int main()
{  int count=1,i;  int child;printf("Before create son,the father's count is:%d\n",count);
if(!(child=vfork())){  for(i=0;i<100;i++)
{  printf("This is son, The i is: %d\n", i);if(i==70) break;     }printf("This is son, his pid is: %d and the count is: %d\n", getpid(), ++count);exit(0);
}
else
printf("After son, This is father, his pid is: %d and the count is: %d,and the child is: %d\n",getpid(),count,child);
}显示结果:
…… ……
This is son, The i is: 68
This is son, The i is: 69
This is son, The i is: 70
This is son, his pid is: 4434 and the count is:2
After son, This is father, his pid is: 4433 and the count is: 2, and the child is: 4434

相关文章:

操作系统实验——线程与进程

如果代码或文章中&#xff0c;有什么错误或疑惑&#xff0c;欢迎交流沟通哦~ ## 进程与线程的区别 1. **各自定义**&#xff1a; 进程是操作系统进行资源分配和调度的一个独立单位&#xff0c;具有一定独立功能的程序关于某个数据集合的依次运行活动。 线程被称为轻量级的进程…...

最强端侧多模态模型MiniCPM-V 2.5,8B 参数,性能超越 GPT-4V 和 Gemini Pro

前言 近年来&#xff0c;人工智能领域掀起了一股大模型热潮&#xff0c;然而大模型的巨大参数量级和高昂的算力需求&#xff0c;限制了其在端侧设备上的应用。为了打破这一局限&#xff0c;面壁智能推出了 MiniCPM 模型家族&#xff0c;致力于打造高性能、低参数量的端侧模型。…...

Spring Boot中如何查询PGSQL分表后的数据

数据库用的pgsql&#xff0c;在表数据超过100w条的时候执行定时任务进行了分表&#xff0c;分表后表名命名为原的表名后面拼接时间&#xff0c;如原表名是card_device_trajectory_info&#xff0c;分表后拼接时间后得到card_device_trajectory_info_20240503&#xff0c;然后分…...

如何学习一个新技能

1. 提出想法 2.找到学习方法&#xff0c;学习路径 3.开始学 参考视频&#xff1a;如何成为超速学习者&#xff1f;快速学会任何新技能&#xff01;_哔哩哔哩_bilibili...

sklearn之logistic回归

文章目录 logistic回归logit logistic回归 logistic regression被称之为logistic回归&#xff0c;对于logistic这个单词来说&#xff0c;他本身的翻译其实不太容易&#xff0c;比较有名的译法是对数几率回归&#xff0c;我也认为这种译法是比较合适的&#xff0c;虽然并非logi…...

Warning: Each child in a list should have a unique “key“ prop.

问题描述&#xff1a; 使用ProTable的时候&#xff0c;报错如下 原因分析&#xff1a; 根据报错内容可以分析出&#xff0c;表格数据缺少唯一key&#xff0c; <PaginationTablecolumns{columns}pagination{{pageSize: 10,current: 1,showSizeChanger: true,showQuickJum…...

JavaSE:StringBuilder和StringBuffer类

1、引言 在上一篇文章中&#xff0c;我们理解了字符串的常用方法&#xff0c;细心的同学大概已经发现&#xff0c;不管是将字符串中的字符转变为大写或小写&#xff0c;或是完成字符串的替换&#xff0c;又或是去除空白字符等等&#xff0c;只要涉及到字符串的修改&#xff0c…...

C语言在线编程网站:探索编程的奥秘与深度

C语言在线编程网站&#xff1a;探索编程的奥秘与深度 在数字世界的浩瀚海洋中&#xff0c;编程已成为连接现实与虚拟的桥梁。而C语言&#xff0c;作为编程领域的经典之作&#xff0c;其深度与广度令无数探索者着迷。为了满足广大编程爱好者的需求&#xff0c;C语言在线编程网站…...

Android 之广播监听网络变化

网络状态变化监听帮助类 NetBroadcastReceiverHelper public class NetBroadcastReceiverHelper {private static final String TAG "NetBroadcastReceiverHelper";private static final String NET_CHANGE_ACTION "android.net.conn.CONNECTIVITY_CHANGE&qu…...

Hono 框架使用经验谈

Hono&#x1f525;是一个小型、快速并开源的 Serverless Web 框架&#xff0c;用 TypeScript 写就。它适用于任何JavaScript运行时&#xff1a;Cloudflare Workers&#xff0c;Fastly ComputeEdge&#xff0c;Deno&#xff0c;Bun&#xff0c;Vercel&#xff0c;Netlify&#x…...

mac 下配置mysql的全局环境变量

前言 如果你还没有安装mysql&#xff0c;请参考这篇文章手把手教你MAC本地数据库的安装与使用&#xff1a;mysql python (pymysql)【一】 - 知乎 正文 1.打开终端&#xff0c;输入命令”echo $SHELL“,显示当前的shell ⚠️本人使用的终端shell是zsh&#xff0c;如果你使用…...

小红书云原生 Kafka 技术剖析:分层存储与弹性伸缩

面对 Kafka 规模快速增长带来的成本、效率和稳定性挑战时&#xff0c;小红书大数据存储团队采取云原生架构实践&#xff1a;通过引入冷热数据分层存储、容器化技术以及自研的负载均衡服务「Balance Control」&#xff0c;成功实现了集群存储成本的显著降低、分钟级的集群弹性迁…...

Python实现解码二进制数据以匹配给定的C++结构体

要在Python中实现解码二进制数据以匹配给定的C结构体Ytest&#xff0c;你需要了解每个字段在结构体中的偏移量&#xff08;由于结构体内存对齐&#xff0c;这些偏移量可能与字段的顺序和大小不完全对应&#xff09;。不过&#xff0c;在没有指定内存对齐的情况下&#xff0c;我…...

实施阶段(2024年5月)

【项目活动1】斐波拉契数列第n项的值&#xff1f; 数学思想&#xff1a;第一项和第二项的值都为1&#xff0c;从第三项开始值为前两项的和。 方法一&#xff1a;迭代 迭代变量&#xff1a;f1和f2 迭代表达式&#xff1a;f1,f2f2,f1f2 计数器&#xff1a;i 迭代表达式运算…...

(delphi11最新学习资料) Object Pascal 学习笔记---第13章第3节 (弱引用是系统托管的 )

13.4.2 弱引用是系统托管的 ​ 弱引用的托管是一个非常重要的内容。换句话说&#xff0c;系统会在内存中保存一个弱引用列表&#xff0c;当对象被销毁时&#xff0c;系统会检查是否有任何弱引用指向该对象&#xff0c;如果有&#xff0c;系统会将实际引用赋值为 nil&#xff0…...

安装WordPress

第 1 步&#xff1a;下载并解压 wget https://wordpress.org/latest.tar.gz 然后使用以下命令提取包&#xff1a; tar -xzvf latest.tar.gz 第 2 步&#xff1a;创建数据库 比如数据库名称为wordpress&#xff0c;编码格式为 utf8mb4_general_ci 第 3 步&#xff1a;设置wp-con…...

【STL库源码剖析】list 简单实现

从此音尘各悄然 春山如黛草如烟 目录 list 的结点设计 list 的迭代器 list 的部分框架 迭代器的实现 容量相关相关函数 实现 insert 在指定位置插入 val 实现 push_back 在尾部进行插入 实现 erase 在指定位置删除 实现 pop_back 在尾部进行删除 实现 list 的头插、头删 实现…...

web前端框架设计第十一课-常用插件

web前端框架设计第十一课-常用插件 一.预习笔记 1.路由的基础使用 2.动态路由 3.嵌套路由 二.课堂笔记 三.课后回顾 –行动是治愈恐惧的良药&#xff0c;犹豫拖延将不断滋养恐惧...

Java基础-注解

注解本质是继承了Annotation接口的一个接口 首先&#xff0c;我们通过键值对的形式可以为注解属性赋值&#xff0c;像这样&#xff1a;Hello&#xff08;value “hello”&#xff09;。 接着&#xff0c;你用注解修饰某个元素&#xff0c;编译器将在编译期扫描每个类或者方…...

SpringCloud之SSO单点登录-基于Gateway和OAuth2的跨系统统一认证和鉴权详解

单点登录&#xff08;SSO&#xff09;是一种身份验证过程&#xff0c;允许用户通过一次登录访问多个系统。本文将深入解析单点登录的原理&#xff0c;并详细介绍如何在Spring Cloud环境中实现单点登录。通过具体的架构图和代码示例&#xff0c;我们将展示SSO的工作机制和优势&a…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

React核心概念:State是什么?如何用useState管理组件自己的数据?

系列回顾&#xff1a; 在上一篇《React入门第一步》中&#xff0c;我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目&#xff0c;并修改了App.jsx组件&#xff0c;让页面显示出我们想要的文字。但是&#xff0c;那个页面是“死”的&#xff0c;它只是静态…...