山东大学2018级操作系统实验一

题目描述

编写一个多进程并发执行程序。父进程每隔 3秒重复建立两个子进程,首先创建的让其执行 ls 命令,之后创建执行让其执行 ps 命令,并控制 ps 命令总在 ls 命令之前执行。

实验思路

父进程要创建两个子进程,两次使用fork(),第一个子进程来执行ls命令,第二个执行ps命令,使用pause()使得第一个子进程阻塞,(通过信号来控制ps命令在ls命令之前执行),等到第二个子进程通过kill命令向第一个子进程发送信号,第一个子进程接到信号后再执行ls命令。

实验涉及的知识点

1、fork()系统调用语法:
#include <unistd.h>
pid_t fork(void);
fork成功创建子进程后将返回子进程的进程号,不成功会返回-1。
2、exec系统调用有一组6个函数,本实验中选用了execlp()
1)execlp()系统调用语法:
#include<unistd.h>
int execlp(const char * file,const char * arg,…);
execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。如果用常数0来表示一个空指针,则必须将它强制转换为一个字符指针,否则它将解释为整形参数,如果一个整形数的长度与char * 的长度不同,那么exec函数的实际参数就将出错。如果函数调用成功,进程自己的执行代码就会变成加载程序的代码,execlp()后边的代码也就不会执行了。
2)execve()系统调用语法:
#include <unistd.h>
int execve(const char *path, const char *argv[], const char * envp[]);
path 要装入的新的执行文件的绝对路径名字符串.
argv[] 要传递给新执行程序的完整的命令参数列表(可以为空).
envp[] 要传递给新执行程序的完整的环境变量参数列表(可以为空).
Exec执行成功后将用一个新的程序代替原进程,但进程号不变,它绝不会再返回到调用进程了。如果exec调用失败,它会返回-1。
3、wait() 系统调用语法:
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid,int *status,int option);
status 用于保留子进程的退出状态
pid可以为以下可能值:
-1等待所有PGID等于PID的绝对值的子进程
1等待所有子进程
0等待所有PGID等于调用进程的子进程
大于0等待PID等于pid的子进程
option规定了调用waitpid进程的行为:
WNOHANG没有子进程时立即返回
WUNTRACED没有报告状态的进程时返回
wait和waitpid执行成功将返回终止的子进程的进程号,不成功返回-1。
4、getpid()系统调用语法:
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
getpid返回当前进程的进程号,getppid返回当前进程父进程的进程号
5、kill系统调用语法:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
pid 接收信号的进程号
signal要发送的信号
kill发送成功返回接收者的进程号,失败返回-1。
6、pause系统调用语法:
#include <unistd.h>
int pause(void);
pause挂起调用它的进程直到有任何信号到达。调用进程不自定义处理方法,则进行信号的默认处理。只有进程自定义了信号处理方法捕获并处理了一个信号后,pause才会返回调进程。pause总是返回-1,并设置系统变量errno为EINTR。
7、sleep系统调用语法:
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
seconds指定进程睡眠的秒数
如果指定的秒数到,sleep返回0。
8、signal系统调用语法为:
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signum要捕捉的信号
handler进程中自定义的信号处理函数名
signal调用成功会返回信号处理函数的返回值,不成功返回-1,并设置系统变量errno为SIG_ERR。
9、SIGINT信号:
程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。
10、父进程将信号的处理方式设置为捕获时,捕获函数对子进程也是有效的。
子进程会继承父进程的信号处理方式。

头文件

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

typedef void (*sighandler_t)(int);

void showLs(){
	
	printf("child one to continue");

}

主程序

#include "pro1.h"
int main(int argc, char *argv[])
{

	int count = 0;
	while (count <= 3)
	{
		//child one  and child two
		pid_t pid1, pid2;
		//create  child one
		pid1 = fork();
		//register the processng interrupt function
		signal(SIGINT, (sighandler_t)showLs);
		//child two status
		int status;
		//control  cycles
		if (pid1 < 0)
		{ //failed to create child one
			fprintf(stderr, "child one fork failed\n");
			exit(-1);
		}
		else if (pid1 == 0)
		{ /*child one*/
			printf("I am child one process %d,my father is %d\n", getpid(), getppid());
			pause();
			printf("process %d is continue to run\n", getpid());
			execlp("/bin/ls", "ls", NULL);
		}
		else
		{
			/* father */
			printf("I am parent process %d\n ", getpid());
		
			//create  child two
			pid2 = fork();
			if (pid2 < 0)
			{ //failed to create child two
				fprintf(stderr, "child two fork failed\n");
				exit(-1);
			}
			else if (pid2 == 0)
			{ /*child two*/
				printf("I am child two process %d,my father is %d\n", getpid(), getppid());
				status = execlp("/bin/ps", "ps", NULL);
			}
			else
			{ /* father */
				waitpid(pid2, &status, 0);
				kill(pid1, SIGINT);
			}
			/*all child process completed and exit*/
			wait(NULL);
			printf("cycle %d , all child process completed\n", count);
		}
		count++;
		//sleep 3 s
		sleep(3);
	}
}

  • 8
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值