操作系统课程设计4_进程创建

一.实验目的

1.重温进程概念,理解Linux中的进程。

2.理解Linux中进程产生的方式,理解fork和clone的差别。

3.了解Linux中的线程。

 

二.实验内容

1.编制C程序,用fork()系统调用创建一个子进程。

2.使用clone()调用创建一个Linux子进程,子进程调用execvp执行系统命令ls。

 

三.实验步骤和结果

1、实验内容1:fork

(1)编写C程序fork_example.c

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
int main()
{
	pid_t childpid;
	int retval;
	int status;
	childpid = fork();
	if(childpid>=0)
	{
		if (childpid==0)
		{
			printf("CHILD:I am the child process!\n");
			printf("CHILD:Here's my PID:%d\n",getpid());
			printf("CHILD:My parent's PID is:%d\n",getppid());
			printf("CHILD:The value of fork return is:%d\n",childpid);
			printf("CHILD:Sleeping for 1 second...\n");
			sleep(1);
			printf("CHILD:Enter an exit value(0 to 255):");
			scanf("%d",&retval);
			printf("CHILD:Goodbye!\n");
			exit(retval);
		}
		else
		{
			printf("PARENT:I am the parent process!\n");
			printf("PARENT:Here's my PID:%d\n",getpid());
			printf("PARENT:The value of my child's PID is %d\n",childpid);
			printf("PARENT:I will now wait for my child to exit.\n");
			wait(&status);
			printf("PARENT:Child's exit code is:%d\n",WEXITSTATUS(status));
			printf("PARENT:Goodbye!\n");
			exit(0);
		}
	}
	else
	{
		perror("fork");
		exit(0);
	}
}

(2)使用命令cc -o fork_example fork_example.c编译

 

(3)编译成功后,使用命令./ fork_example运行,子进程的退出值输入3。运行结果如下图:

 

2.实验内容2:clone

(1)编写clone_example.c源文件

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sched.h>
#include <signal.h>
#define FIBER_STACK 8192

int lc=2019;

int do_something(){
	printf("This is son, the pid is:%d, the lc is: %d\n", getpid(), lc);
    lc=2020;
    char* argv[] = {"ls", "-l", NULL}; // 构造 vector,注意argv[0] 是占用参数
	if (execvp("ls", argv) == -1) { // 替换代码段和数据段,并重新从 ls 入口点执行
		perror("exec");
	}

    exit(1);
}
int main() {
    char * stack;
    stack = (char*)malloc(FIBER_STACK);
    if(!stack) {
        printf("The stack failed\n");
        exit(0);
    }

	printf("creating son thread!!!\n");
	int cpid=clone(do_something, (char *)stack + FIBER_STACK, CLONE_VM|CLONE_VFORK, 0);
	int pid=waitpid(cpid,0,0);
	if (pid==0){
		perror("waiting");
	}

	printf("This is father, my pid is: %d, the lc is: %d\n", getpid(), lc);

    free(stack);
    exit(1);
}

(2)使用命令cc -o clone_example clone_example.c编译

 

(3)编译成功后,使用命令./ clone_example运行。运行结果如下图:

该实验结果表明,成功通过clone创建了子进程,该子进程修改了变量lc的值,并且同时调用 execvp 执行系统命令 ls。父进程等待子进程执行完毕后,返回父进程的提示语句。

 

四.实验问题与分析

1、调用fork的进程叫做父进程,由此调用而产生的进程叫子进程。父进程返回的是子进程的pid,子进程从fork()返回的是0。

 

2、clone()系统调用中常见的flags参数:

(1)CLONE_FS。

如果使用这个标志的话,父进程和子进程文件系统信息,包括根目录、当前工作目录、umask等。

(2)CLONE_FILES。

如果使用这个标志的话,父进程和子进程共享文件描述符表。

(3)CLONE_SIGHAND。

如果使用这个标志的话,父进程和子进程共享信号处理函数表。

(4)CLONE_VM。

如果使用这个标志的话,那么父进程和子进程运行在同一个虚拟地址空间(确切地说,是使用同一个代码段和数据段,但不使用同一个堆栈)。

(5)CLONE_VFORK

如果使用这个标志的话,父进程被挂起,直至子进程释放虚拟内存资源

 

五.实验总结

本次实验,我首先重温了进程概念,理解Linux中的进程的含义。通过理解fork和clone的差别,分别用fork和clone来创建子进程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值