实验目的
- 本实验要求学生了解什么是信号,掌握软中断的基本原理;掌握中断信号的使用、进程的创建以及系统计时器的使用。
- 通过对本实验的学习,学生能够学会进程的创建方法,更能加深对Linux中的信号机制的认识,并会使用软中断信号来实现进程间的通信。
实验内容
学生根据test2.c理解以下内容:
- 1.父进程接受到软中断信号(SIGQUIT)后,向其子进程分别发送整数值为 16的软中断信号,子进程获得对应软中断信号后,终止运行。
- 2.父进程调用wait()函数等待子进程终止,然后自我终止。
- 3.由父进程创建一个子进程,通过终端输入Crtl+\组合键向父进程发
- 送SIGQUIT软中断信号发送给父进程。
编程实现以下内容:
- 1.由一个父进程创建两个子进程,之后通过终端输入Crtl+\组合键向父进
- 程发送软中断信号,终止两个子进程以及父进程。
- 2.由一个父进程创建一个子进程,之后该子进程再创建一个孙进程,通过终端输入Crtl+\组合键向父进程发送软中断信号,依次终止孙进程、子进程、父进程。
实验环境
Ubuntu 12.04 LTS
Device name: oslinux-virtual-machine
Memory: 1001.2MiB
Processor: 13th Gen Intel Core i5-13500HX
Graphics: Unknown
OS type: 32-bit
Disk: 20.3GB
实验步骤
实验 1:编译并运行程序test2.c,当按下Crtl+\组合键时,打印出子进程结束的信息,最后打印出父进程结束的信息。
- 1.创建一个子进程;
- 2.子进程分别等待信号16,如果收到信号则显示结束信息,并发出结束信号;
- 3.父进程等待SIGQUIT信号,如果收到信号则向子进程发送信号16,接着 等子进程结束,如果都结束了则显示结束信息,并退出进程。
实验2:编写两种三个进程通信情况。
- 1.由一个父进程创建两个子进程,之后通过终端输入Crtl+\组合键向父进 程发送软中断信号,终止两 个子进程以及父进程。
- 2.由一个父进程创建一个子进程,之后该子进程再创建一个孙进程,通过 终端输入Crtl+\组合键向父进程发送软中断信号,依次终止孙进程、子 进程、父进程。
- 3.实验报告附程序源码及对重要代码语句的解释和程序运行结果。
实验结果
结果展示
test2运行结果
进程14571由父进程14570创建,输入Crtl+\后,子进程14571被父进程终止,随后父进程终止。
实验2第一种情况运行结果
子进程14763和14764由父进程14762创建,输入Crtl+\后,子进程分别被父进程终止,随后父进程终止。
实验2第二种情况运行结果
子进程15325由父进程创建,孙进程15326由子进程15325创建,输入Crtl+\后,孙进程被子进程终止,子进程被父进程终止,随后父进程终止。
核心代码
实验2第一种情况源码
#include<cstdio>
#include<cstdlib>
#include<csignal>
#include<unistd.h>
#include <sys/wait.h>
#include "iostream"
using namespace std;
void waiting();
void stop();
int wait_mark;
int main()
{
pid_t p1, p2;
p1 = fork();
if (p1 != 0) { // if p1 is parent process
lockf(1, 1, 0);
cout << "Parent Process " << getpid() << endl;
lockf(1, 0, 0);
wait_mark = 1;
::signal(SIGQUIT, reinterpret_cast<__sighandler_t>(stop));
p2 = fork();
if (p2 == 0) { // if p2 is child process
lockf(1, 1, 0);
cout << "Child Process " << getpid() << " created by " << getppid() << endl;
lockf(1, 0, 0);
::signal(SIGQUIT, SIG_IGN);
wait_mark = 1;
::signal(16, reinterpret_cast<__sighandler_t>(stop));
waiting();
lockf(1, 1 , 0);
cout << "Child Process " << getpid() << " is killed by parent " << getppid() << endl;
lockf(1, 0, 0);
::exit(0);
}
waiting();
kill(p1, 16); // send signal 16 to end the process p1
wait(NULL);
kill(p2, 16); // send signal 16 to end the process p2
wait(NULL);
lockf(1, 1, 0);
cout << "parent process if killed" << endl;
lockf(1, 0, 0);
::exit(0);
} else if (p1 == 0) { // if p1 is child process
lockf(1, 1, 0);
cout << "Child Process " << getpid() << " created by " << getppid() << endl;
lockf(1, 0, 0);
::signal(SIGQUIT, SIG_IGN);
wait_mark = 1;
::signal(16, reinterpret_cast<__sighandler_t>(stop));
waiting();
lockf(1, 1 , 0);
cout << "Child Process " << getpid() << " is killed by parent " << getppid() << endl;
lockf(1, 0, 0);
::exit(0);
}
return 0;
}
void waiting( )
{
while (wait_mark != 0);
}
void stop()
{
wait_mark=0;
}
实验2第二种情况源码
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>
#include <sys/wait.h>
void waiting();
void stop();
int wait_mark;
int main() {
int p1, p2;
while ((p1 = fork()) == -1);
if (p1 > 0) //if p1 is parent process
{
lockf(1, 1, 0);
printf("parent process is %d \n", getpid());
lockf(1, 0, 0);
wait_mark = 1;
signal(SIGQUIT, stop);
waiting();
kill(p1, 16); //send signal 16 to end the process p1
wait(0); //waiting for the ending of p1
lockf(1, 1, 0);
printf("parent process is killed!\n");
lockf(1, 0, 0);
exit(0); //quit from the parent process
} else //if p1 is child process
{
while ((p2 = fork()) == -1);
if (p2 > 0) //if p2 is parent process
{
lockf(1, 1, 0);
printf("child process %d is created by the parent %d \n", getpid(), getppid());
lockf(1, 0, 0);
signal(SIGQUIT, SIG_IGN);
wait_mark = 1;
signal(16, stop);
waiting();
kill(p2, 16); //send signal 16 to end the process p2
wait(0); //waiting for the ending of p2
lockf(1, 1, 0);
printf("child process %d is killed by parent %d \n", getpid(), getppid());
lockf(1, 0, 0);
exit(0); // p1 quit
} else //if p2 is child process
{
lockf(1, 1, 0);
printf("grandson process %d is created by the parent %d \n", getpid(), getppid());
lockf(1, 0, 0);
signal(SIGQUIT, SIG_IGN);
wait_mark = 1;
signal(16, stop);
waiting();
lockf(1, 1, 0);
printf("grandson process %d is killed by parent %d \n", getpid(), getppid());
lockf(1, 0, 0);
exit(0); // p2 quit
}
}
return 0;
}
void waiting() {
while (wait_mark != 0);
}
void stop() {
wait_mark = 0;
}