12进程

这节主要介绍,父子进程共享文件、fork基于的copy on write、exit(0)与_exit(0)的区别、atexit()终止处理程序。

首先父子进程共享文件:

直接献上一个例子:

#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>

#define ERR_EXIT(m) 	do 	{ 		perror(m); 		exit(EXIT_FAILURE); 	} while(0)

int main(int argc, char *argv[])
{
	signal(SIGCHLD, SIG_IGN);
	printf("before fork pid = %d\n", getpid());
	int fd;
	fd = open("test.txt", O_WRONLY); //在父进程中打开一个文件
	if (fd == -1)
		ERR_EXIT("open error");
	pid_t pid;
	pid = fork();
	if (pid == -1)
		ERR_EXIT("fork error");

	if (pid > 0)
	{
		printf("this is parent pid=%d childpid=%d\n", getpid(), pid);
		write(fd, "parent", 6);  //从父进程中向文件写
		sleep(3);
	}
	else if (pid == 0)
	{
		printf("this is child pid=%d parentpid=%d\n", getpid(), getppid());
		write(fd, "child", 5);   //从子进程中向文件写
	}
	return 0;
}

可以看出,在子进程中不用重新打开文件,直接利用父进程中的文件描述符就可以对文件进行操作,这里值得注意的是有可能父进程先写进去子进程再写的时候直接把

父进程写的内容给覆盖了,这是犹豫子进程写的时候父进程可能已经结束,这是用sleep控制一下会看出效果,这个大家自己动手试一试。

fork的copy on write特性:

意思就是父子进程各自都有自己的地址空间,但是都共享一些初始未变的东西,当子进程中有改变的时候就会拷贝一份放到自己的地址空间中去,看例子:

#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>

#define ERR_EXIT(m) 	do 	{ 		perror(m); 		exit(EXIT_FAILURE); 	} while(0)

int gval = 100;

int main(int argc, char *argv[])
{
	signal(SIGCHLD, SIG_IGN);
	printf("before fork pid = %d\n", getpid());

	pid_t pid;
	pid = fork();
	if (pid == -1)
		ERR_EXIT("fork error");

	if (pid > 0)
	{
		sleep(1);
		printf("this is parent pid=%d childpid=%d gval=%d\n", getpid(), pid, gval);
		sleep(3);
	}
	else if (pid == 0)
	{
		gval++;
		printf("this is child pid=%d parentpid=%d gval=%d\n", getpid(), getppid(), gval);
	}
	return 0;
}

打印的结果:父进程还是100而子进程是101。

exit(0)与_exit(0)的区别:

1、exit(0)是C函数库提供的,而_exit(0)是linux系统的系统调用。

2、

这个就是执行时候的区别,_exit(0)会直接去到内核中去,而exit(0)会调用终止程序和清除i/o缓冲。

int main(int argc, char *argv[])
{
	printf("hello world");
	//fflush(stdout);
	//_exit(0);
	exit(0);
}
int main(int argc, char *argv[])
{
	printf("hello world");
	//fflush(stdout);
	_exit(0);
	//exit(0);
}
int main(int argc, char *argv[])
{
	printf("hello world\n");
	//fflush(stdout);
	_exit(0);
	//exit(0);
}
int main(int argc, char *argv[])
{
	printf("hello world");
	fflush(stdout);
	_exit(0);
	//exit(0);
}

可以看出请没清缓冲去的区别,这里\n和fflush都是有清的功能,只是为了让大家了解一下。

下面是终止处理程序,简单了解一下:

#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>

#define ERR_EXIT(m) 	do 	{ 		perror(m); 		exit(EXIT_FAILURE); 	} while(0)

void my_exit1(void)
{
	printf("my exit1 ...\n");
}

void my_exit2(void)
{
	printf("my exit2 ...\n");
}

int main(int argc, char *argv[])
{
	//下面是两次安装
	atexit(my_exit1);
	atexit(my_exit2);
	_exit(0);
}

可以看出终止处理程序的调用次序和安装次序正好相反,了解了解即可。

最后给出一个有意思的小程序,供大家分享一下父子进程的运行流程:

int main(int argc, char *argv[])
{
	fork();
	fork();
	fork();
	printf("ok\n");
	return 0;
}

运行一下看看能打印多少个OK,自己动手画一下运行线图可以理解清楚。

答案是:8个。

时间: 2024-10-11 13:16:55

12进程的相关文章

#每日Linux小练习#12进程的详细分析

经常被问到进程和线程的区别,今天对进程进行详细的分析讨论. 一.进程的定义 进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就创建了一个进程,在这个过程中,伴随着资源的分配和释放.可以认为进程是一个程序的一次执行过程. 二.进程与程序的区别 程序时静态的,它是一些保存 在磁盘上得指令的有序集合,没有任何执行的概念. 进程是一个动态的概念,它是程序执行的过程,包括创建.调度和消亡. 三.linux系统中进程的表示 在linux系统中,进程由一个叫task_struct的结构体描述,也

# 进程/线程/协程 # IO:同步/异步/阻塞/非阻塞 # greenlet gevent # 事件驱动与异步IO # Select\Poll\Epoll异步IO 以及selectors模块 # Python队列/RabbitMQ队列

1 # 进程/线程/协程 2 # IO:同步/异步/阻塞/非阻塞 3 # greenlet gevent 4 # 事件驱动与异步IO 5 # Select\Poll\Epoll异步IO 以及selectors模块 6 # Python队列/RabbitMQ队列 7 8 ############################################################################################## 9 1.什么是进程?进程和程序之间有什么

操作系统之进程篇1

1.进程的出现,让我们需要对进程进行分离存储,而有了内存管理:需要不同进程有条不紊的往前推进而有了进程调度. 2.为什么要有进程?什么是进程? 为了实现程序的并发执行,我们发明了进程.一个程序加载到内存后就变成了进程. 3.注意不是所有进程都一定要终结,实际上,许多系统进程是不会终结的,除非强制终止或关闭计算机. 4.什么时间造成进程的产生? 1)系统初始化:在一个系统初始化时,将有许多进程产生,产生的这些进程是系统正常运行必不可少的. 2)执行进程创立程序:如双击了一个可执行文件. 3)用户请

python学习之-- 进程 和 线程

python 进程/线程详解 进程定义:以一个整体的形式暴露给操作系统管理,它里面包含对各种资源的调用,内存的管理,网络接口的调用等等,对各种资源管理的集合,就可以叫做一个进程. 线程定义:线程是操作系统能够进行运算调度的最小单位(是一串指令的集合).它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 另说明:进程是不能直接操作CPU执行的,每个进程的执行都是默认创建一个主线程来操作CPU进行执行指令集合

(49)LINUX应用编程和网络编程之四 Linux进程全解

补充: 1.  C程序的执行过程: C编译器调用链接器,链接器设置可执行程序文件的启动起始地址(启动例程),启动例程获得内核传递来的 命令行参数和环境变量值,为调用main函数做准备.[实际上该启动例程常用汇编语言编写],如果将启动例程换做C语言就是:exit(main(argc,argv)); main(int argc,char *argv[],char *engv[]);argv为指向参数的各个指针所构成的数组. 2.exit做一些清理处理(标准IO库的清理关闭操作为所有打开的流调用fcl

Linux进程管理工具详解:htop、glances、dstat

1.进程相关知识     1.操作系统的功能:文件系统.网络功能.进程管理.内存管理.安全功能.驱动程序(Linux是一个多任务的操作系统,而且是抢占式的多任务操作系统);.OS其实就是提供虚拟的计算机,进而能够将有限的资源借助于"保护"机制分配多个同时运行的程序,即"进程"使用,从而实现了所谓的多任务 2.程序执行环境有2种: 内核模式:cpu运行内核级指令 用户模式:cpu运行普通指令 3.应用程序运行普通指令,其实是直接运行于cpu上:应用程序运行特权指令,是

操作系统_第二章_进程与线程

2018-06-30 1.进程:对正在运行的程序的一个抽象 2.一个进程就是一个正在执行的程序的实例 3.快速的切换称为:多道程序设计 4.一个进程是某种类型的一个活动,它有程序,输入,输出,以及状态 5..四种主要的事件会导致进程的创建 系统初始化 正在运行的程序执行了创建进程的系统调用 用户请求创建一个新进程 一个批处理作业的初试化 6.停留在后台进程的称为守护进程 7.shell中键入sort就可以创建进程了 8.内存一般使用写时复制的方法进行内存共享 9.进程的终止 正常退出 出错退出

Linux系统管理(一)——进程管理

************************************如有写错或者不准之处还请指出************************************ 1-1Linux进程介绍与进程管理的作用 Linux系统管理员面临的最复杂的任务之一就是追踪运行在系统中的程序.想要监看这些运行的 程序,那就要熟悉ps命令的用法.下面将介绍ps,pstree,top,kill,killall,pkill和nice等命令. (1)进程简介 进程:是指当程序运行在系统上时,称之为进程.(或者另

操作系统判断

1. 操作系统的所有程序都必须常驻内存.╳ 2. 进程获得处理机而运行是通过申请而得到的. ╳ 3. 通过任何手段都无法实现计算机系统资源之间的互换. ╳(中断等都可以) 4. 进程控制块中的所有信息必须常驻内存. ╳ 5. 一旦出现死锁, 所有进程都不能运行. ╳(运行不能结束) 6. 所有进程都挂起时, 系统陷入死锁. ╳(挂起的意思是什么?) 7. 优先数是进程调度的重要依据, 一旦确定不能改变. ╳ 8. 同一文件系统中不允许文件同名, 否则会引起混乱. ╳ 9. 用户程序有时也可以在核