实验目的
本实验要求学生了解什么是信号,掌握软中断的基本原理;
掌握中断信号的使用、进程的创建以及系统计时器的使用。
通过对本实验的学习,学生能够学会进程的创建方法,更能加深对Linux中的信号机制的认识,并会使用软中断信号来实现进程间的通信。
实验内容
实验 1:编译并运行程序test2.c,当按下Crtl+\组合键时,打印出子进程结束的信息,最后打印出父进程结束的信息。
创建一个子进程; 子进程分别等待信号16,如果收到信号则显示结束信息,并发出结束信号;
父进程等待SIGQUIT信号,如果收到信号则向子进程发送信号16,接着等子进程结束,如果都结束了则显示结束信息,并退出进程。
实验2:编写两种三个进程通信情况。
由一个父进程创建两个子进程,之后通过终端输入Crtl+\组合键向父进程发送软中断信号,终止两个子进程以及父进程。
由一个父进程创建一个子进程,之后该子进程再创建一个孙进程,通过终端输入Crtl+\组合键向父进程发送软中断信号,依次终止孙进程、子进程、父进程。
本文章仅提供实验2的两种代码。
代码1,由一个父进程创建两个子进程,之后通过终端输入Crtl+\组合键向父进程发送软中断信号,终止两个子进程以及父进程:
#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) {
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) {
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);
wait(nullptr);
kill(p2, 16);
wait(nullptr);
lockf(1, 1, 0);
cout << "parent process if killed" << endl;
lockf(1, 0, 0);
::exit(0);
} else if (p1 == 0) {
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,由一个父进程创建一个子进程,之后该子进程再创建一个孙进程,通过终端输入Crtl+\组合键向父进程发送软中断信号,依次终止孙进程、子进程、父进程:
#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) {
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) {
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);
wait(nullptr);
kill(p2, 16);
wait(nullptr);
lockf(1, 1, 0);
cout << "parent process if killed" << endl;
lockf(1, 0, 0);
::exit(0);
} else if (p1 == 0) {
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;
}
注意:本系列文章代码均为C++代码,使用gcc编译会报错,应当使用g++编译。
文章评论