OS函数:sleep-exit-wait

本文介绍了Linux中的sleep函数、exit系统调用和wait函数的用法及其相互影响。通过示例代码展示了它们如何影响进程的执行顺序和状态,包括如何创建并发执行的进程以及如何处理子进程的结束。同时,提到了僵尸进程的概念以及如何避免其产生。
摘要由CSDN通过智能技术生成

sleep()函数

sleep函数的作用就休眠指定的秒数,休眠期间让出CPU,其它进程可以执行。

下面示例一和示例二的区别就是,前者有sleep函数,在父进程进行休眠的时候让出了cpu,此时子进程可以执行了,从而达到了交替睡眠,交替执行的目的

后者是注释了sleep函数所以,父进程在执行完自己的进程之后才让出cpu让子进程来执行

示例一:

#include <unistd.h>
#include <stdio.h>
#include<sys/types.h>
int main()
{
	int p1,i;
	while ((p1=fork())==-1);//负数:如果出错,则fork()返回-1,此时没有创建新的进程。最初的进程仍然循环运行。

	if (p1>0)
    for (i=0;i<5;i++)
    {
        printf("I am parent %d.\n",i);
        sleep(1);
    }
	else
    for (i=0;i<5;i++)
    {
        printf("I am child %d.\n",i);
       sleep(1);
    }
	return 0;
}



/*
执行结果:

slee@s-magicbook:~/s_code$ ./shiyan2_0
I am parent 0.
I am child 0.
I am parent 1.
I am child 1.
I am parent 2.
I am child 2.
I am parent 3.
I am child 3.
I am child 4.
I am parent 4.

*/

示例二


#include <unistd.h>
#include <stdio.h>
#include<sys/types.h>
int main()
{
	int p1,i;
	while ((p1=fork())==-1);//负数:如果出错,则fork()返回-1,此时没有创建新的进程。最初的进程仍然循环运行。

	if (p1>0)
    for (i=0;i<5;i++)
    {
        printf("I am parent %d.\n",i);
        //sleep(1);
    }
	else
    for (i=0;i<5;i++)
    {
        printf("I am child %d.\n",i);
       //sleep(1);
    }
	return 0;
}


/*
执行结果:

slee@s-magicbook:~/s_code$ ./shiyan2_0
I am parent 0.
I am parent 1.
I am parent 2.
I am parent 3.
I am parent 4.
I am child 0.
I am child 1.
I am child 2.
I am child 3.
I am child 4.

*/

exit系统调用:

exit这个系统调用是用来终止一个进程的。无论在程序中的什么位置,只要执行到exit系统调用,进程就会停止剩下的所有操作,清除包括PCB在内的各种数据结构,并终止本进程的运行。

示例

#include<stdlib.h>
#include<stdio.h>
int main()
{
    printf("this process will exit!\n");
	exit(0);
	printf("never be displayed!\n");
}


/*

执行结果:

slee@s-magicbook:~/s_code$ ./shiyan2_0
this process will exit!

*/


never be displayed!没有输出是因为遇到进程遇到exit就戛然而止了

wait函数

进程一旦调用了wait,就立即阻塞自己,由wait自动分析当前进程的某个子进程是否已经退出,如果让它找到了这样一个已经变成僵尸的子进程, wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。pid = wait(NULL); 如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1。

函数原型

pid_t wait (int * status);

函数说明

参数 status 是一个整形指针。如果status不是一个空指针,则终止进程的终止状态将存储在该指针所指向的内存单元中。如果不关心终止状态,可以将 status参数设置为NULL。
status 不是NULL时子进程的结束状态值会由参数 status 返回,而子进程的进程识别码作为函数返回值返回。
调用 wait 函数时,调用进程将会出现下面的情况:

  • 如果其所有子进程都还在运行,则阻塞。
  • 如果一个子进程已经终止,正等待父进程获取其终止状态,则获取该子进程的终止状态然后立即返回。
  • 如果没有任何子进程,则立即出错返回。

返回值

如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno 中。

需要都头文件

#include <sys/types.h> #include <sys/wait.h>

#include <unistd.h>
#include <stdio.h>
#include<sys/types.h>
#include<stdlib.h>
#include <sys/wait.h>

int main()
{
	pid_t j,p1,i;
	while ((p1=fork())==-1);
	if (p1>0)
    {
        wait(0);//这里不用返回值,直接调用就可以阻塞本进程
    	for (i=0;i<5;i++)
    	{   
        	printf("I am parent %d.\n",i);
        	sleep(1);
    	}
    }else{
    	for (i=0;i<5;i++)
    	{
       		printf("I am child %d.\n",i);
       		sleep(1);
    	}
    	exit(0);
   	}
	return 0;
}



/*执行结果:

slee@s-magicbook:~/s_code$ gcc -o shiyan2_0 shiyan2_0.c
slee@s-magicbook:~/s_code$ ./shiyan2_0
I am child 0.
I am child 1.
I am child 2.
I am child 3.
I am child 4.
I am parent 0.
I am parent 1.
I am parent 2.
I am parent 3.
I am parent 4.



如果把wait(0)注释了就会出现下面的结果:

slee@s-magicbook:~/s_code$ gcc -o shiyan2_0 shiyan2_0.c
slee@s-magicbook:~/s_code$ ./shiyan2_0
I am parent 0.
I am child 0.
I am parent 1.
I am child 1.
I am parent 2.
I am child 2.
I am parent 3.
I am child 3.
I am child 4.
I am parent 4.
*/

exit和sleep的配合构造僵尸进程

在一个进程调用了exit之后,该进程并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构。在Linux进程的5种状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集。sleep的作用是让进程休眠指定的秒数,在子进程已经退出,而父进程正忙着睡觉,不可能对它进行收集,这样,就能保持子进程10秒的僵尸状态。

#include<stdlib.h>
#include<sys/wait.h>
#include <stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{   pid_t  pid ,pr;
    pid=fork();
    while( pid <0);
    if(pid == 0 ){
        printf("this is child process with pid of  %d\n",getpid());  
        exit(0);  
	}
     else{
        sleep(10); 
        pr=wait(NULL);//pr是子进程的号
        printf("I catch a child process with pid of %d\n",pr);
	}
}


/*
执行结果:

slee@s-magicbook:~/s_code$ gcc -o shiyan2_0 shiyan2_0.c
slee@s-magicbook:~/s_code$ ./shiyan2_0
this is child process with pid of  3936
I catch a child process with pid of 3936


*/

综合练习:

实现三个进程并行

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <stdlib.h> 
#include <stdio.h>
int main(){ 
int pid1, pid2, i=1; 
	while ( (pid1=fork()) ==-1);//fork一个子进程1
	if (pid1==0) { 
		printf ("This is child process 1, pid=%d\n",getpid() ) ; 
		sleep (1) ; 
	for (i='A' ;i<='Z' ; i++) { 
		printf ("Child process1 print %c\n",i ); 
		sleep (1) ; 
	} 
		exit (0) ; 
	} else{ //对于父进程main
		while ( (pid2=fork()) ==-1) ; //再fork一个子进程2
		if (pid2==0) { 
			printf ("This is child process 2, pid=%d\n", getpid() ) ; 
			sleep (1) ; 
			for (i='a' ; i<='z' ; i++) { 
				printf ("Child process2 print :%c \n", i) ; 
				sleep (1) ; 
			} 
			exit (0) ; 
		} else {
			printf ("This is a parent process, pid=%d\n", getpid()) ; 
			sleep (1) ; 
			for (i=1; i<=26; i++) { 
				printf ("Parent process print :%d\n", i) ; 
				sleep (1) ; 
				
			}
			exit (0) ; 
		}
	}
}



/*
执行结果:

slee@s-magicbook:~/s_code$ gcc -o shiyan2_0 shiyan2_0.c
slee@s-magicbook:~/s_code$ ./shiyan2_0
This is child process 1, pid=5025
This is a parent process, pid=5024
This is child process 2, pid=5026
Child process1 print A
Parent process print :1
Child process2 print :a 
Parent process print :2
Child process1 print B
Child process2 print :b 
Parent process print :3
Child process1 print C
Child process2 print :c 
Parent process print :4
Child process1 print D
Child process2 print :d 
Parent process print :5
Child process1 print E
Child process2 print :e 
Parent process print :6
Child process1 print F
Child process2 print :f 
Child process1 print G
Parent process print :7
Child process2 print :g 
Child process1 print H
Parent process print :8
Child process2 print :h 
Child process1 print I
Parent process print :9
Child process2 print :i 
Child process2 print :j 
Child process1 print J
Parent process print :10
Child process2 print :k 
Child process1 print K
Parent process print :11
Child process1 print L
Child process2 print :l 
Parent process print :12
Child process1 print M
Child process2 print :m 
Parent process print :13
Child process1 print N
Parent process print :14
Child process2 print :n 
Child process1 print O
Child process2 print :o 
Parent process print :15
Child process1 print P
Child process2 print :p 
Parent process print :16
Child process1 print Q
Parent process print :17
Child process2 print :q 
Child process1 print R
Child process2 print :r 
Parent process print :18
Child process1 print S
Child process2 print :s 
Parent process print :19
Child process1 print T
Child process2 print :t 
Parent process print :20
Child process1 print U
Parent process print :21
Child process2 print :u 
Child process2 print :v 
Child process1 print V
Parent process print :22
Parent process print :23
Child process1 print W
Child process2 print :w 
Child process1 print X
Parent process print :24
Child process2 print :x 
Parent process print :25
Child process1 print Y
Child process2 print :y 
Child process1 print Z
Parent process print :26
Child process2 print :z 


*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值