Unix下C语言----进程控制

UNIX环境高级编程第二版(英文)与源码实战 本章节展示了UNIX系统下文件操作和文件描述符管理的基础知识,包括文件操作的基本系统调用open()read()write()close(),以及文件的随机访问和锁定。同时,深入探讨了文件描述符的高级管理,包括dup()dup2()和fcntl()调用,以及非阻塞和异步I/O操作,从而帮助开发者更好地理解和运用UNIX文件系统。在下一节,我们将深入探讨标准I/O库及缓冲流解析。 阅读详情

 一、进程基本环境

  进程是程序的一次运行,是运行在自己的虚拟地址空间的一个具有独立功能的程序。进程是分配和释放资源的基本单位,当程序执行时,系统创建进程,分配内存和CPU等资源;进程结束时,系统回收这些资源。

 

 

  1进程概念

     进程通常由程序、数据和进程控制块(PCB)三个部分组成的。其中,程序部分描述了进程锁要完成的功能;数据部分为进程提供了运行所需的堆栈和私有数据;进程控制块则含有进程的描述和控制信息,几种反应进程的动态特性,是系统识别和控制进程的依据。

 

  1)进程与程序

     进程是程序的一次执行,故程序是一个静态的概念,本身可以作为一种软件资源长期保存;而进程是程序的执行过程,是动态概念,有一定的生命周期,具有产生、发展和消亡的过程。

     程序是一个规划,它计划了所要执行的代码和所要完成的动作;进程是一位执行者,它依照程序的设计,申请资源,计算数据,并完成预定的任务。一个程序可以同时由多个进程执行;一个进程也可以有顺序地执行若干程序。

    进程不能脱离具体程序而存在,程序规定了相应进程所要完成的动作;程序不能脱离进程而应用,进程将程序的设想变成可能。

 

  2)进程与线程

    线程又名轻负荷进程,它是在进程基础上程序的一次执行,一个进程可以拥有多个线程。

    线程没有独立的资源,它共享进程的ID,共享进程的资源。

    线程是UNIX最小的调度单位,目前有系统级调度和进程级调度两种线程调度实行方式:系统级调度的操作系统以线程为单位进程调度;进程级调度的操作系统以仍以进程为单位进行调度,进程再为其上运行的线程提供调度控制。

 

  3)前台进程和后台进程

    用户在Shell提示符处键入命令,创建进程,此后该进程接管终端,Shell中不能再输入其它的命令,知道进程执行完毕,才将终端控制权返回Shell并显示用户提示符。这样子的进程是前台进程。

   如果用户在输入Shell命令时,在命令串上加上"&",于是就可以同时运行进程和执行Shell操作。这样子的进程就是后台进程,后台进程并不接管终端,因此必须是非交互式的。

 

  4)守护进程

    守护进程是与终端无关,常住后台执行的特殊进程。UNIX中最著名的2个守护进程是:

sysproc进程:UNIX的第一个进程,标志号为0,能合理地调度系统中运行的进程,负责将进程从硬件交换区调入内存(换入)或将进程从内存调到硬盘交换区(换出)。

init进程:系统初始化进程,进程标志号为1,是除sysproc外所有进程的祖先。

 

 

  5)父子进程

    进程采用树型结构管理。当一个进程启动另一个进程时,被启动的进程就是子进程,原进程就是父进程。在UNIX中,使用系统调用fork创建进程。fork复制了父进程的数据、堆栈段和进程环境,因此,子进程继承了父进程的某些环境,并且共享父进程的代码段。但子进程也拥有自己的环境,父子进程以并行的执行同一程序的不同分支。

 

  6)进程状态

    进程在运行过程中具有运行状态、就绪状态和睡眠状态。

    运行态:进程已经分配到CPU,正在处理机上执行时的装填。同一时刻处于运行态的进程不能大于CPU的数目。运行态又可以细分用户态和和心态两种。用户态:如果进程正在运行用户的代码,进程就处于用户态。核心态:如果进程出现系统调用或系统中断,运行操作系统的内部代码,进程就处于和心态。

    就绪态:进程已具备运行条件,但是其它进程正占用CPU,所以暂时不能运行而等待分配CPU的状态。处于就绪态的进程一旦获得了CPU,就能立刻运行。

    睡眠态:进程正在等待某种时间的发生而暂时不能运行的状态。处于睡眠态的进程尚不具备运行条件,即使CPU空闲,它也无法使用。

 

  7)进程调度

    UNIX系统的机场南横调度属于多级反馈循环调度,它的每个进程都有一个优先级,级别高的进程优先执行,级别低的进程延后执行,相同级别的进程循环调度。默认情况下,系统可以动态地调整正在运行中进程的优先级,以提供最佳相应时间;同时也允许用户自主更改进程的优先级别。

 

 

2.进程的标识

 1)进程的标识号

    UNIX中的每个进程都具有唯一的标志号,操作系统采用一个非负整数标识每个进程。进程启动时,系统为进程分配标志号(进程ID);进程终中止后,标志号可以重新使用。但任意时刻,一个标志号只对应一个进程。比如0代表sysproc进程,1代表init进程。

    UNIX中读取进程ID号的函数如下:

   

 

  2)进程的用户标识号

    当进程由用户启动时,该用户的标识号就是进程的实际用户标识,该用户的组标志号就是进程的实际组标识号。

    进程在操作文件时,都要进程权限检查,但进程的实际用户标识号和实际组标识号仅用于系统记账,参与权限检查的是进程的有效用户标识号和有效组标识号。一般情况下,实际标识号和有效标准号相一致,但系统允许更改进程的有效标识号。

    UNIX中读取进程用户ID号的函数如下:

   

 

 

  3.进程命令行

    每个完整的C程序都是从main函数开始执行的,其原型如下:

    int main();

    int main(int argc,char  *argv[]);

    其中命令行参数是在启动程序执行时,在Shell中以空白分开的字符串。main函数的参数传递运行程序的命令行参数,其中整型argc记载了命令行的参数个数,指针数组argv[]给出了命令行参数的内容,它的每一个元素指向一个iecunchu命令行参数的字符串。

ex:

编译和运行arg1.c

 

 

4.环境变量

  环境变量中记载了很多可供程序共享或者不经常改变的信息。UNIX下C程序中有2中获取环境变量值的方法:全局变量法和函数调用法。

  1)全局变量法

  UNIX系统中采用了一个指针数组来存储全部环境值:

  extern char **environ;

  ex:

 

  2)函数调用法

  UNIX中操作环境变量的函数如下:

  #include<stdlib.h>

  char *getenv(char *name);

  int putenv(const char *string);

  getenv以字符串形式返回环境变量name的值,如果参数name为NULL或者环境列表中无name变量,返回NULL。

  函数putenv增加、修改或删除环境变量。参数string指向一个字符串,格式为:“name=value”。

二、进程的生命周期

  1.进程的创建

    在UNIX中,系统调用fork是创建新进程的方法,它的原型为:

    #include<unistd.h>

    pid_t fork();

    调用fork创建的子进程,将共享父进程的代码空间,复制父进程数据空间,如堆栈等。此时子进程会获得父进程中的所有变量的一份拷贝,尽管父子进程中的变量名相同,但却存储在内存中的不同地方,因此不能奢望通过内存变量完成父子进程之间的消息传递,此变量非彼变量。

    如果fork调用失败,返回-1,如果调用成功,则在父进程中返回子进程的标识号,在子进程返回0。

 

 【注:】子进程可以在通过getpid得到自身的进程标志号,通过getppid得到父进程标志号。但父进程无法获取子进程的标志号,故fork成功时在父进程中返回创建的子进程的标志号,可以弥补这一缺陷。

 

  以下设了一个创建子进程的例子:

 

 

  【注】创建子进程主要应用两个方面:

   (1)复制代码,父子进程执行不同的代码段。这种情况在网络服务程序中最常见:父进程侦听,当socket收到连接请求后创建子进程,然后继续侦听。子进程负责建立socket连接、接收通信内容并执行处理过程。

   (2)执行新程序。子进程被创建后,离开调用exec命令执行别的程序。

 

 2.新程序的执行

   在shell中如何执行程序?下面以ls命令的执行为例说明:

   --shell进程接收用户输入的命令"ls"

   --shelle创建子进程,并进入等待状态。

   --子进程读取程序"ls"的代码,替换从父进程继承的执行代码

   --子进程执行"ls"程序

   --进程"ls"执行完毕,子进程退出。

   --shell被激活,重新接管终端,处理用户交互式输入

 

  1)exec函数族

  UNIX提供一组替换进程执行代码的函数,它们的原型如下:

 

exec函数组调用成功时,系统把一个新程序的地址空间代替调用进程的地址空间并装入新程序的内容,同时忽略原exec函数的返回,不执行exec之后的所有语句,系统将从新程序的main函数处开始执行。如果exec函数族调用失败,将返回-1。

2)fork-exec 模型

函数族exec经常应用在子进程中,因此常与函数fork连用,如下:

 

 

 3)vfork-exec 模型

  在大多数情况下,fork-exec模型在创建子进程后立即执行新程序,并不是用父进程的数据,因此UNIX提供了一个更好的vfork,它的原型如下:

#include<unistd.h>

pid_t vfork();

函数vfork与fork在功能和调用形式上类似,也能创建子进程,但二者有如下区别:

(1)Vfork创建的紫禁城并不复制父进程的数据,在随后的exec调用中系统会复制新程序的数据到内存中,继而避免了一次数据复制过程。

(2)父进程以vfork方式创建子进程后将被阻塞,直到子进程退出或执行exec调用才继续运行。

当子进程只有来执行新程序时,vfork-exec模型比fork-exec模型具有更高的效率,这种方法也正是shell创建新进程的方式。

 

(4)system模型

在UNIX中,我们也可以使用system函数完成新程序的执行,其原型如下:

#include<stdlib.h>

int system(char *string);

函数system阻塞调用它的进程,并执行字符串string的shell命令,它可以理解为vfork-exec模型的交易表达方式:

 

 

if(vfork()==0)

{

  execl("/bin/ls","-C",string,0);

  exit(0);

}

 

system调用成功,返回执行命令的shell状态,或者返回-1或其他错误。

 

3.进程的休眠

函数sleep使调用进程进入休眠状态,其原型如下:

#include<unistd.h>

unsigned int sleep(unsigned int seconds);

进程调用函数sleep后休眠seconds妙,直到时间结束或收到不可忽略信号为止。

 

4.进程的终止

  UNIX中,终止进程的函数如下:

  #include<unistd.h>

  void exit(int status);

  进程调用函数exit终止自己的运行,并且释放所占的系统资源。参数status的低8位记载了进程的终止状态,进程终止后将这个状态返回它的父进程。

 

5.进程的同步

系统调用wait可以实现父子进程之间的同步,其原型如下:

#include<sys/types.h>

#include<sys/wait.h>

pid_t wait(int *status);

pid_t waitpid(pid_t pid,int *status, int options);

函数wait挂起调用它的进程,知道它的任一子进程退出或者收到一个不能忽略的的信号位置,如果父进程执行wait调用前就已经有子进程退出,则立即返回。函数成功调用后返回结束运行子进程的ID,否则返回-1。参数status返回子进程退出的状态。

本处设计了一个进程同步的例子,父进程fork一个子进程后进入wait阻塞,等待子进程运行结束并打印子进程结束状态。如下:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

操作系统进程控制实验代码(c语言) 用C语言编程模拟进程管理,至少要有:创建新的进程;查看运行进程;换出某个进程;杀死运行进程以及进程之间通信等功能。 PCB结构通常包括以下信息:进程名,进程优先数,轮转时间片,进程所占用的CPU时间,进程的状态,当前队列指针等。可根据实验的不同,PCB结构的内容可以作适当的增删。 立即下载

相关推荐

进程控制的算法模拟 c语言实现

1、程序中有创建、撤消、阻塞、唤醒、挂起、激活、改变优先数(K0)、改变状态(STATE)、查看PCB功能模块,为每个模块建立一个程序。 2、PCB(进程控制块)可采用数组数据结构,每个数组元素即PCB块可包含N0(外部名),K0(优先数),CHA(状态)三项。

C语言——进程管理

文章目录进程基本概念进程的属性进程控制相关函数进程创建进程等待进程结束多个进程间的关系进程组时间片分配调度策略和参数优先级设定进程同步线程线程的创建线程结束、挂起、取消互斥 进程基本概念 进程是具有一定功能的程序关于一个数据集合的一次执行过程。Linux系统支持多个进程同时进行,每个进程属性中的安全信息里都设定有一个优先级,系统根据优先级来决定各个进程从CPU获得的时间片的大小。 Linux内核把进程成为任务(task),进程的虚拟地址空间分为用户虚拟地址空间和内核虚拟地址空间,所有进程个共享内核虚拟地址空

塔通天的博客 2449

上海市大数据中心笔试模拟试卷

为帮助考生熟悉上海市大数据中心笔试的题型、考点及答题逻辑,以下整理了一份的模拟试卷,涵盖大数据专业知识、行政职业能力测试(行测)、公共基础知识(含上海本地政策)三大核心模块,并附详细答案解析。

一叶之秋的博客 1815

C语言-进程控制编程

一篇学懂多进程编程

qq_55869380的博客 1767

学术报告系列(二) - 智能自主作业机器人感知与控制技术及发展趋势

收集整理于2022年模式识别高峰论坛湖南大学王耀南院士报告(报名题目:智能自主作业机器人感知与控制技术及发展趋势)

Make something people want. 4696

nRF24L01模块性能调优笔记:基于STC8H的SPI通信,如何突破700包/秒的传输瓶颈?

本文详细介绍了如何通过SPI通信优化、nRF24L01寄存器配置和STC8H系统级调优,突破700包/秒的传输瓶颈。从硬件设计到软件实现,提供了一套完整的性能调优方案,特别适合需要高性能无线通信的嵌入式开发者。

weixin_42525211的博客 181

操作系统用C语言编写程序,模拟实现创建新的进程:查看运行进程;换出某个进程:杀死运行进程等功能。

进程管理实验目的实验内容实验步骤实验代码 实验目的 1.理解进程的概念,明确进程和程序的区别 2.理解并发执行的实质。 3.掌握进程的创建、睡民、撤销等进程控制方法。 实验内容 用C语言编写程序,模拟实现创建新的进程:查看运行进程;换出某个进程:杀死运行进程等功能。 实验步骤 进程 1.进程的含义 进程是程序在一个数据集合上的运行过程,是系统资源分配和调度的一个独立单位。一个程序在不同数据集合上运行,乃至一个程序在同样数据集合上的多次运行都是不同的进程。 2.进程的状态 通常,一个进程必须具有就绪、执行和阻

Sum 1万+

2024年捡垃圾指南:E5 V3/V4服务器CPU怎么选?从游戏多开到深度学习,附华南X99主板搭配清单

本文详细解析2024年E5 V3/V4服务器CPU的选购策略,涵盖游戏多开、深度学习等多种应用场景。通过对比E5 V3与V4系列的制程、功耗及性能差异,提供高性价比的CPU型号推荐及华南X99主板搭配方案,帮助用户在有限预算下打造高效能工作站。

weixin_42549451的博客 1578

C进程控制--上篇

C进程控制基础linux进程的结构linux进程状态进程的各种标识符进程的内存映像创建进程子进程继承父进程的内容子进程与父进程的区别孤儿进程fork与vfork 基础 1.进程是一个动态的实体,是程序的一次执行过程。 2.进程是在内存中,程序是在硬盘中。 3.进程是操作系统资源分配的基本单位。 4.区别进程、线程、程序。 5.线程在进程内部,是比进程更小的能独立运行的基本单位。 6.线程不拥有系统资源,与其他线程共享进程的全部资源。 7.一个线程可撤销另一个线程,同一进程中多个线程并行执行。 8.进程树的

wxd296931635的博客 381

利用python语言进行相机标定

利用python语言进行相机标定 目录利用python语言进行相机标定一、相机标定相关原理1.相机标定简介2.坐标映射2.1图像坐标系1)图像坐标系(Pixel coordinate system)2)成像平面坐标系(Retinal coordinate system)3)摄像机坐标系(Camera coordinate system)4)世界坐标系(World coordinate system)二、相机标定算法流程1.镜头畸变1.1径向畸变1.2切向畸变2.相机标定算法求解外参内参和单应矩阵关系求解(张

qq_44818951的博客 4700

C语言 操作系统 进程控制

一、进程控制 ●基本要求:模拟操作系统内核对进程的控制和管理:包括进程的创建和撤 销、进程状态的切换和简单的内存空间管理。 内容 模拟触发进程状态转换的事件:采用键盘控制方法来模拟触发进程状态切换的事件(例如输入 1 代表创建新进程、2 执行进程时间片到、3 阻塞 执行进程、4 唤醒第一个阻塞进程、5 终止执行进程),实现对应的控制程序。 数据结构 定义管理每个进程的数据结构 PCB:包含进程名称、队列指针、分配的物理内存区域(基址和长度)。每创建一个进程时,需要为其创建 PCB 并 分配空 闲内存空间,对

li1441853031的博客 6084

Zemax显微镜设计:从物镜到目镜的完整光学系统优化

本文详细介绍了使用Zemax进行显微镜光学系统设计的完整流程,从物镜到目镜的优化技巧。通过实战案例和关键参数设置,帮助读者掌握数值孔径、视场角等核心概念,实现高分辨率显微镜设计。文章特别强调了系统级优化和公差分析的重要性,为科研和工业检测提供可靠的光学解决方案。

weixin_42549451的博客 438

UNIX环境C语言进程控制

一、进程ID 进程ID即是进程标识,每一个进程都会有一个唯一的非负整数来作为它的进程ID。 ID为0的进程通常是调度进程,也可称为交换进程,该进程是内核的一部分,不执行硬盘上的程序,因此也被称为系统进程。 ID为1的进程通常是init进程,init通常读取与系统有关的初始化文件,,并将系统引导到一个状态。init进程绝不会终止,它是一个普通的用户进程,但是它以超级用户特权运行,init会称为...

weixin_30409849的博客 158

YOLOv11 损失函数进阶:Varifocal Loss 让正负样本精度双升

创建self.alpha = alpha # 正样本权重系数self.gamma = gamma # 聚焦系数self.lambda_reg = lambda_reg # 回归损失权重# 分类损失:Varifocal Classification Loss# 正样本权重:基于预测置信度# 计算 BCE 损失并加权cls_loss = cls_loss.sum() / (cls_true.sum() + 1e-6) # 按正样本数归一化。

m0_71589036的博客 441

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Unix下C语言编程之进程控制

fork与 vfork的区别 调用fork创建的子进程, 将共享父进程的代码空间, 复制父进程数据空间, 如堆栈等,fork之后,子进程和父进程都会继续执行fork调用之后的指令。 子进程对父进程中的同名变量进行修改并不会影响其在父进程中的值。 该函数被调用一次,但返回两次。两次返回是在不同的地址空间返回的,是在各自的进程地址空间返回的,其中子进程的返回值是0,而父进程的返回值则是新子进程的

477

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

UNIX下C语言编程与实践30-UNIX 进程控制:vfork-exec 模型与 fork-exec 模型的效率对比

本文对比分析了UNIX系统中fork-exec和vfork-exec两种进程控制模型的核心差异。fork-exec采用写时复制机制,安全性高但略有性能开销;vfork-exec完全共享内存,效率极致但存在严重安全风险。测试显示在现代硬件上,vfork-exec仅比fork-exec快30%左右。建议优先使用fork-exec或POSIX标准接口posix_spawn,仅在内存极度有限的嵌入式系统等特殊场景才谨慎选用vfork-exec,并严格确保子进程立即执行exec/exit。现代UNIX系统通过优化fo

文石_2009的博客 992

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

UNIX环境C语言编程(7)-进程控制

进程标识 fork函数 exit函数 wait、waitpid函数 竞态条件 exec函数族 改变用户ID、组ID 解释器文件 system函数 用户标识

justkk的专栏 745

c语言编程进程同步控制,UNIX环境C语言编程(18)-线程控制

1、线程属性•intpthread_attr_init(pthread_attr_t*attr);•intpthread_attr_destroy(pthread_attr_t*attr);•涉及分离状态、堆栈起始地址、堆栈大小、警戒区域大小、并发级别•设置/获取分离状态•intpthread_attr_getdetachstate(constpthread_attr_t*restrictattr...

weixin_31937289的博客 172

什么是进程控制块?os为什么要为每个进程创建一个进程控制块?_用 C 语言写一个简单的 Unix Shell(1)...

写 Unix shell 是我正在 RC 研究的一个项目。这是第一部分,后续会有一系列的文章。免责声明:我不是编写 shell 这个课题的专家,我是一边自学一边分享我的发现。shell 是什么?关于这一点已经有很多书面资料,所以对于它的定义我不会探讨太多细节。只用一句话说明:shell 是允许你与操作系统的核心作交互的一个界面(interface)。shell 是怎样工作的?shell解析用户输入...

weixin_39756192的博客 134

unix进程控制

今天看了apue第一章Unix System Overview的进程控制,对fork有了一些理解。有一个例程如下: [code="c"]#include"apue.h" #include int main(void) { char buf[MAXLINE]; pid_t pid; int status; printf("%% "); while(fgets(...

现实照进梦想 212

unix环境高级编程学习笔记(一)

图1-3 ls命令简单实现 #include "apue.h" #include <dirent.h> int main(int argc,char *argv[]) { DIR *dp; struct dirent *dirp; //判断是否有路径 if (argc != 2) err_quit("usage: ls directory_name"); //

qq_44610809的博客 514

UNIX系统编程小结(三)----进程相关

进程即一个程序的动态执行。引用apue上的一句话:"A thorough understanding of the UNIX System's process control is essential for advanced programming". 一.总述 1.进程的开始 在C语言中,进程是由一个main函数开始。 ...

weixin_30748995的博客 88

实验五 linux进程控制,实验五进程控制及通信系统调用使用

实验五进程控制及通信系统调用使用 实验五 进程控制及通信系统调用使用四、实验内容本实验要求在 LINUX/UNIX 环境下用 C 语言编写三个多进程并发执行的程序,基本涉及了 LINUX/UNIX 进程管理子系统中较为常用的有关进程控制的系统调用。实验内容如下:⑴使用 fork()系统调用创建进程,使父、子进程分别运行不同的代码 (要求子进程在父进程之前运行):子进程:①以长格式显示当前目录的情况...

weixin_33156085的博客 602

windows c语言 守护进程,C语言中的守护进程有没有一种方法可以实现?

我对C中的守护进程有一个普遍的问题,我现在还没有看到答案.有没有办法实现守护进程的控制,如约定或标准?– 还有进一步的解释 –我已经看到多个文档教授基础知识如何在C中创建一个守护进程.分叉,关闭文件描述符,更改root等等……没问题.当进程进入无限循环时(当创建守护进程时 – 也就是说),它们都会停止.但这只是编写守护进程的一半;你必须以某种方式控制它.我可以让它以不同的方式工作,但我感觉还有更多...

weixin_39779975的博客 208

UNIX系统编程2<C代码>2

UNIX系统编程22     配合UNIX系统编程2使用。 01tst_fork.c: #include #include int main() { pid_t pid = fork(); switch (pid) { case -1: perror("fork"); goto err_fork; case 0: //由子进程执行

887
上一篇: 操作系统复习概要
下一篇: 85篇精彩的经典古文
wolfzone025
博客等级 码龄16年 35粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值