代码编织梦想

1.进程的创建

①调用fork函数的进程为父进程,调用后生成一个子进程;
②创建子进程成功时,父进程中fork函数的返回值是子进程的进程号PID;
③创建子进程失败时,父进程中fork函数的返回值是一个负数;
④子进程复制当前进程中所有变量的值,并复制fork函数调用后父进程剩下的所有代码。
⑤子进程中的进程号PID为0。
⑥需要引入头文件<unistd.h>

另外,可以用getpid函数获取当前进程的进程号PID

Current_Pid=getpid()

问题举例:

编写程序,使用系统调用fork()创建如下的进程树,当此程序运行时,在系统中有一个父进程和多个子进程活动,父进程等子进程运行结束后退出。
每个进程循环5次显示不同的字符串。假设X的初值为2022,父进程的字符串内容包括自己的学号、姓名、变量X的值;子进程字符串包括进程PID、子进程序号(子进程1或2)、变量X的值。每次循环X的值加5。记录屏幕上的显示结果,并分析变量X的变化规律。
在这里插入图片描述

求解代码:

#include<stdio.h>
#include<unistd.h>  //使用fork函数和getpid函数都需要导入这个头文件

int main(void)
{
	int pid1,pid2;  //分别用两个变量记录两个子进程的进程号
	int x=2022;    
	int temppid;   //记录某时刻的进程号
	
	pid1=fork();   //父进程用fork函数创建一个新的子进程

	if(pid1<0)     //如果子进程的进程号小于1则表示进程创建失败
	{
		printf("第一个子进程创建失败!\n");
	}
	else if(pid1==0)  //如果进程号为0表示当前进程就是第一个子进程,则执行下面的代码段
	{
		pid2=fork(); //创建一个新的子进程
		if(pid2<0)    //创建第二个子进程失败的情况
		{
			printf("第二个子进程创建失败!\n");
		}
		else if(pid2==0)  //第二个子进程执行的代码段
		{
			int k=0;
			for(k=0;k<5;++k)
			{
				temppid=getpid();
			    printf("PID=%d 串联创建的子进程2  X=%d\n",temppid,x);
                x+=5;
			}
		}
		else //第一个子进程执行的代码段
		{
			int j=0;
			for(j=0;j<5;++j)
			{
				temppid=getpid();
			    printf("PID=%d 串联创建的子进程1  X=%d\n",temppid,x);                                                                                                                                                                                                                                                                      
			    x+=5;
			}
		}
	}
	else  //父进程执行的代码段
	{
		int i=0;
		for(i=0;i<5;++i)
		{
			temppid=getpid();
		    printf("学号:123 姓名:小明 X=%d\n",x);
            x+=5;
		}
	}

	return 0;
}

运行效果:

在这里插入图片描述

2.进程的替换

①调用execlp函数可以进行进程替换;
②execlp函数的参数是需要执行的带有完整路径的程序名以及一个指针(注意是可执行文件而不是源代码C文件,指针一般取NULL);
③进程替换后该进程的数据区和代码区都变为替换到的程序的数据和代码。

问题举例:

修改上一题编写的程序,将子进程改为独立的程序,父进程创建子进程并进行程序替换,观察程序执行时屏幕出现的现象,并分析原因。

求解代码:

①父进程代码:

#include<stdio.h>
#include<unistd.h>

int main(void)
{
	int pid1,pid2;
	int x=2022;
	int temppid;
	
	pid1=fork();
	
	if(pid1<0)
	{
		printf("子进程1创建失败!\n");
	}
	else if(pid1==0)
	{
		pid2=fork();
		
		if(pid2<0)
		{
			printf("第二个子进程创建失败!\n");
		}
		else if(pid2==0)
		{
			execlp("./2.2.2",0);
		}
	    else
	    {
	        execlp("./2.2.1",0);
        }
	}
	else
	{
        wait(NULL);
		int i=0;
		for(i=0;i<5;++i)
		{
			temppid=getpid();
		    printf("学号:123 姓名:小明 X=%d\n",x);
            x+=5;
		}
	}
	
	return 0;
}

②子进程1代码(即父进程中调用的2.2.1):

#include<stdio.h>
#include<unistd.h>

int main(void)
{
	int x=2022;
	int i;
	int pid;
	
	for(i=0;i<5;++i)
	{
		pid=getpid();
		printf("PID=%d 子进程1  X=%d\n",pid,x);
        x+=5;
	}
	return 0;
}

③子进程2代码(即父进程中调用的2.2.2):

#include<stdio.h>
#include<unistd.h>

int main(void)
{
	int x=2022;
	int i;
	int pid;
	
	for(i=0;i<5;++i)
	{
		pid=getpid();
		printf("PID=%d 子进程2  X=%d\n",pid,x);
        x+=5;
	}
	return 0;
}

运行效果:

在这里插入图片描述

3.进程的阻塞

①调用wait函数可以实现进程的阻塞;
②调用wait函数的进程必须等到其所有子进程结束后才能继续执行;
③wait函数的参数为一个指针,一般传入NULL。

4.进程终止

①调用exit函数可以实现进程的终止;
②终止当前进程的同时不会终止该进程的所有子孙进程。孤儿进程会被init进程收养。
③使用exit函数需要引入函数库<stdlib.h>

孤儿进程示例代码

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main(void)
{
	int pid;

	pid=fork();
	
	if(pid<0)
	{
		printf("子进程创建失败!\n");
	}
	else if(pid==0)
	{
		int i;
		for(i=0;i<10;++i)
		{
			sleep(2);
			printf("父进程的PID=%d\n",getppid());
		}
	}
	else
	{
		sleep(3);
		printf("父进程输出自己的PID=%d\n",getpid());
                                  exit(0);
	}

	return 0;
}

运行效果:

在这里插入图片描述

5.进程的挂起

①使用sleep函数挂起一个进程;
②sleep函数的参数是需要休眠的时间,以秒计算。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/hanmo22357/article/details/128005238

用fork创建进程树-爱代码爱编程

创建一个如下图所示的进程树。用getpid()和getppid()梳理其关系。 要注意的是fork之后的子进程和父进程共享代码段,并且如果有写的情况下会有各自的数据段。 #include<stdio.h> #include<unistd.h> #include<stdbool.h> #include<sy

linux:exec系列进程替换函数_weiv.的博客-爱代码爱编程

一.exec替换进程映像 引: fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号

linux fork() 进程树的两种实现方法_木风feng的博客-爱代码爱编程

Linux fork()进程树的两种实现方法 刚完成操作系统的实验一,其中附加题是使用fork()实现一颗满二叉树形态的进程树,觉得好玩,做完之后就记录一下。 1. 暴力的做法 最简单粗暴的做法,当然就是直接把

进程创建和替换——fork和exec_mineyuer的博客-爱代码爱编程

fork fork是UNIX系统中产生新进程的唯一办法 fork的作用是复制当前进程,生成子进程,子进程从fork的位置继续执行。fork函数的特点概括起来就是“调用一次,返回两次”,在父进程中调用一次,在父进

进程深入学习笔记(3)--进程的程序替换(exec)和一个简单的shell实现_hansionz的博客-爱代码爱编程

进程深入学习笔记 1.进程的程序替换(exec)(1).替换原理(2).六种替换函数(3).exec类函数用法 2.实现一个简单的shell(1).shell的功能(2).具体过程(3).代码实现

linux进程替换--函数 exec_zhangbaqing的博客-爱代码爱编程_替换进程函数

对 fork 函数,我们知道是创建子进程的,那创建子进程干吗?一般有下面两种情况: 一个父进程希望复制自己,使父进程和子进程同时执行不同的代码段。一个进程要执行不同的程序,在这种情况下,子进程从 fork 返回之后立

操作系统 fork与exec-爱代码爱编程

前言 学习操作系统,首先便要学到process概念。process是什么?Process – a program in execution。七十年代UNIX最先提出多进程的构想,之后该构想便广泛用于linux与unix操作系统中。fork()函数给程序猿们提供了简便的多进程编程方式。 fork() creates new process exec()

linux系统编程————exec进程替换_djh971102的博客-爱代码爱编程

exec函数族:进程替换函数 1、何为进程替换: 1、让父子进程执行不相干的操作;也就是说,在一个运行的程序a中,调用另外的应用程序b。 2、换核不换壳;exec族函数,能够替换进程地址空间中的代码段.text段(对应的堆、栈中的数据都会改变),重新填充新的代码。 2、函数原型: execl系列是变参函数 int execl(const ch

进程替换 --- exec-爱代码爱编程

在 Linux 中,exec 指的是一组函数,一共有 6 个。其中只有 execve() 是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。当进程调用一种 exec 函数时,该进程完全由新程序替换,而新程序则从其 main 函数开始执行。因为调用 exec 并不创建新进程,所以前后的进程 ID (当然还有父进程号、进程组号、当前工作目录……)并未

linux设置已由进程父进程,linux&c 进程控制 课后习题-爱代码爱编程

(声明:本篇博客只是博主自己的理解,加以整理,目的是总结刚学过的进程知识,不一定绝对正确,非常愿意听客官您提出宝贵意见。) Q1:进程中的全局数据段(全局变量),局部数据段(局部变量),静态数据段的分别位于哪个内存地址空间? 答:对于进程的概念,我把它理解一个可执行程序进行的实体,我们c语言代码在变成可执行文件的过程中都会经历下面4步(以我们大家接

操作系统 putty用法 fork() 、 wait() 进程树-爱代码爱编程

Putty putty远程链接虚拟机内的openEuler可以黏贴代码(和win10一样 右键) , 使用方法: 下载putty,在1处输入虚拟机ip地址,若长期使用则在2处保存。IP地址可打开虚拟机的terminal从此处看 两个都试一下能连上就行 有时会弹出这个提示框 这是提示你putty不能确定这个ip是不是你想链接的IP,一般用于远程链接,我

进程篇——进程的运行:exec()系列函数-爱代码爱编程

说明:   本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。   QQ 群 号:513683159 【相互学习】内容来源:   Linux网络编程 exec系列函数   ①函数说明:     fork()函数建立新进程,但只可建立相同程序的副本,原进程保持存

使用exec函数替换当前进程-爱代码爱编程

1 exec介绍 fork函数创建新的进程后,子进程往往要调用一种exec函数以执行另一个程序。当进程调用exec函数时,该进程执行的程序完全替代为新程序,而新程序则从其main函数开始执行。exec只是用磁盘上的一个新程序替换了当前进程的正文段,数据段,堆和栈。 基本的进程控制原语:fork函数创建新进程,exec函数初始执行新的程序,exit函数终止

linux和windows操作系统使用PHP向C/C++传递参数的方法(保姆级)exec()函数详解-爱代码爱编程

相信大家在开发服务器的时候都会遇到需要在PHP中调用C/C++的情况,而想要调用C++必然涉及到传递参数,接下来将会为大家介绍传递PHP在不同的操作系统中向C/C++语言传参的方法。 构建基础的POST/GET方法的表单 HTML代码 <!DOCTYPE html> <html lang="en"> <head&g