Linux编程基础:第6章Linux进程管理 课后习题

本文介绍了Linux编程中关于进程管理的基础知识,包括进程控制块(PCB)、进程状态、进程创建(fork()函数)、进程同步(wait()和waitpid()函数)以及exec函数族的使用。详细解析了进程和程序的区别,给出了多个示例程序及其执行结果,并提出了编程题目,要求创建子进程并实现特定功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《Linux编程基础》黑马程序员/编著 清华大学出版社

目录

一、填空题

二、判断题

三、单选题

四、简答题

1、简单说明程序和进程的区别。

2、分析程序,写出程序的执行结果。

五、编程题

1、编写程序,在程序中创建一个子进程,使父子进程分别打印不同的内容。

2、编写程序,在程序中创建一个子进程,使子进程通过exec更改代码段,执行cat命令。


一、填空题

1、进程的属性保存在一个被称为进程控制块/PCB的结构体中,这个结构体中包括进程控制符/PID、进程组、进程环境、进程的运行状态等。

2、进程在内存中可能会出现不同的状态,通常进程的状态被划分为五种:初始态、就绪态运行态睡眠/挂起态和终止态。

【解析】进程在内存中的状态分为5种,包括:初始态、就绪态、运行态、睡眠(挂起)态和终止态。

3、Linux系统中的进程结构类似树形结构,使用pstree命令可以查看当前系统中的进程树。进程树的顶端是进程init,它是系统启动后创建的第一个进程。

解析使用pstree命令可以查看当前系统中的进程树;系统启动后创建的第一个进程是init,它处于进程树的顶端,负责启动getty进程、设置运行级别和孤儿进程回收等工作,是所有进程的祖先。

4、调用fork()函数成功创建子进程后,父进程中的fork()函数会返回子进程的pid,子进程中的fork()函数会返回0

5、若在程序中通过如下所示的循环创建进程,循环结束后,该进程会创建2^{5}-1(或31)个子进程。

for(int i=0;i<5;i++)
{
	pid=fork();
}

解析在每次调用fork()函数创建子进程后,子进程和父进程都会继续执行for循环,如当前i=1,则在i=0时父进程创建出的子进程与父进程本身都会创建一个子进程,如下图所示:

 因此i=1时fork()函数调用后进程的数量为2^{2},在下一轮循环中,这4个进程又都会创建一个新进程,进程的数量变为2^{3},由此可得,在第5次循环结束后,进程的数量变为2^{5},则子进程的数量为2^{5}-1=31。

二、判断题

1、进程是程序的一次执行过程。(

2、exec函数族的功能是:根据指定的文件名或路径,找到可执行文件,用该文件取代调用该函数的进程中的程序,再从该文件的main()函数开始,执行文件的内容。(√)

3、解决僵尸进程的方法是终止其父进程,使其变为孤儿进程。(

解析通常情况下,解决僵尸进程的方法是终止其父进程。当僵尸进程的父进程被终止后,僵尸进程作为孤儿进程被init接收,init会不断调用wait()函数获取子进程状态,获取已退出的子进程发送的状态信息。孤儿进程永远不会成为僵尸进程。

4、fork()函数执行后,系统会立刻为子进程复制一份父进程的资源。(×

解析Linux系统中的进程机制采用“读时共享,写时复制”的原则,在子进程创建之初并不会复制父进程的全部资源。

5、进程同步机制中的waitpid()函数和wait()函数用于使父进程阻塞等待子进程终止,将子进程进行回收,因此当父进程中调用了这两个函数时,就不会再有僵尸进程产生。(×

解析wait()函数会在有子进程终止时立刻返回,waitpid()函数的一次调用只能回收一个子进程,若因此若子进程数量不唯一时,父进程中调用一次wait()和waitpid(),并不一定能回收所有子进程,也就无法保证所有子进程都被回收,没有僵尸进程产生。

三、单选题

1、在程序中调用fork()函数创建进程,父子进程会获取不同的返回值,下面关于fork()函数的说法,错误的是。(B

A、若子进程创建成功,父进程的fork()返回子进程pid,子进程的fork()返回0。

B、若子进程创建成功,子进程的fork()返回子进程pid,父进程的fork()返回0。

C、若子进程创建失败,父进程的fork()函数返回-1。

D、若子进程创建成功,子进程将从fork()函数调用处之后的代码开始执行。

解析若子进程创建成功,父进程的fork()返回子进程pid,子进程的fork()返回0。

2、下列哪种方法无法查看进程的信息。(C

A、ps B、top C、kill D、查看/proc目录

解析kill命令的功能是通过向进程发送信号控制进程行为。

3、下列哪种方法可以等待接收进程号为pid的子进程的退出状态。(A

A、waitpid(pid,&status,0)

B、waitpid(pid,&status,WNOHANG)

C、waitpid(-1,&status,0)

D、waitpid(-1,&status,WNOHANG)

解析waitpid()函数的第一个参数大于0时,表示回收pid等于该参数的进程,因此排除C、D。若waitpid()函数的第三个参数options为0,waitpid()函数功能与wait()函数功能相同,都阻塞等待子进程的返回状态;若options为WNOHANG,表示子进程若尚未终止,父进程不阻塞等待,立刻返回,因此排除B,选择A。

4、函数waitpid()的返回值等于0时表示的含义是(C

A、等待的子进程已终止

B、终止的子进程不唯一

C、使用选项WNOHANG,且没有子进程退出

D、调用异常终止

解析若options的值为WNOHANG,但调用waitpid()时发现没有已退出的子进程可收集,则返回0。

5、从后台启动进程,应在命令的添加哪个符号?(A

A、& B、# C、* D、~

四、简答题

1、简单说明程序和进程的区别。

程序是“死”的,进程是“活”的,程序是指编译好的二进制文件,它存放在磁盘上,不占用系统资源,是具体的;而进程存在于内存中,占用系统资源,是抽象的。当一次程序执行结束之后,进程随之消失,进程所用的资源被系统回收。

2、分析程序,写出程序的执行结果。

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
    pid_t pid1,pid2;
    if ((pid1 = fork()) == 0)
    {   
        sleep(3);
        printf("child process_1\n");
        exit(0);
        printf("child process_1\n");
    }   
    else
    {   
        if ((pid2 = fork()) == 0)
        {
            sleep(1);
            printf("child process_2\n");
            return 0;
        }
        else
        {
            wait(NULL);
            wait(NULL);
            printf("info1 from parent process\n");
            printf("info2 from parent process\n");
            return 0;
        }
    }
    return 0;
}

程序执行结果如下:

child process_2
child process_1
info1 from parent process
info2 from parent process

五、编程题

1、编写程序,在程序中创建一个子进程,使父子进程分别打印不同的内容

程序实现如下

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
	pid_t pid;
	pid = fork();
	if (pid == -1)
	{
		perror("fork error");
		exit(1);
	}
	else if (pid > 0)
	{
		printf("This is parent process.\n");
	}
	else if (pid == 0)
	{
		printf("This is child process.\n");
	}
	return 0;
}

编译程序并执行,程序的执行结果如下:

This is parent process.
This is child process.

2、编写程序,在程序中创建一个子进程,使子进程通过exec更改代码段,执行cat命令。

程序实现如下:

exec.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
	pid_t pid;
	pid = fork();
	if (pid == -1)
	{
		perror("fork error");
		exit(1);
	}
	else if (pid > 0)
	{
		printf("parent process:pid");
	}
	else if (pid == 0)
	{
		printf("child process\n");
		execlp("cat", "-b", "exec.c", NULL);
		perror("error exec\n");
		printf("child process\n");
	}
	return 0;
}

编译程序并执行,程序的执行结果如下:

parent process:pidchild process
[itheima@localhost itcast]$ #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
	pid_t pid;
	pid = fork();
	if (pid == -1)
	{
		perror("fork error");
		exit(1);
	}
	else if (pid > 0)
	{
		printf("parent process:pid");
	}
	else if (pid == 0)
	{
		printf("child process\n");
		execlp("cat","-b","exec.c",NULL);
		perror("error exec\n");
		printf("child process\n");
	}
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

得闲喝茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值