练习一 软中断一
编写一个程序循环输出“how are you?”,当键盘输入Ctrl+C时终止,当输出次数不超过350次时在此过程中使用Ctrl+C不能中断显示,350次后才能用Ctrl+C中断显示,然后输出“Byebye”.
<Code>
#include<signal.h>
#include<stdio.h>
int flag_signal;
void int_func(int sig)
{
flag_signal=0;
}
main()
{
int i;
while(i<=350)
{
printf("how are you!/n");
i++;
}
signal(SIGINT,int_func); //预设软中断信号处理函数
flag_signal=1;
while(flag_signal==1)
printf("how are you!/n");
printf("BYEBYE!/n");
exit(0);
}
运行结果:
练习二 软中断二
使用软中断实现父子进程同步,父进程先输出A,然后子进程输出B。
<Code>
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
int flag_signal;
void int_func(int sig)
{
flag_signal=0;
}
int main()
{
int p1;
while((p1=fork())==-1);
if(p1>0) //父进程返回
{
printf("A!/n");
sleep(1);
kill(p1,12); //发软中断信号给子进程
wait(0);//等待子进程终止
printf("ok!/n");
exit(0);
}
else
{
signal(12,int_func);
flag_signal=1;
while(flag_signal==1)
{
sleep(1);
}
printf("B!/n");
printf("child exit!/n");
exit(0);
}
}
运行结果:
练习三 软中断三
编写程序完成:
(1) 父进程生成两个子进程P1,P2
(2) 父进程从键盘接收Ctrl+C中断信号
(3) 然后父进程使用系统调用向两个子进程分别发送中止执行信号SIGUSR1和SIGUSR2
(4) 子进程收到各自的信号后分别输出
child 1 killed by father process
child 2 killed by father process,并退出(无次序要求)
(5) 父进程在收到子进程撤消的消息后输出
father kill itself. 父进程最终退出。
<Code>
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int flag_signal;
void waitting()
{
while(flag_signal!=0);
}
void int_func(int sig)
{
flag_signal=0;
printf("中断开始!/n");
}
int main()
{
int p1,p2;
while((p1=fork())==-1);
if(p1==0)
{
sleep(1);
printf("child1 create!/n");
signal(SIGINT,SIG_IGN);
signal(16,int_func);
waitting();
printf("child1 process is killed by parent!/n");
exit(0);
}
else
{
while((p2=fork())==-1);
if(p2==0)
{
sleep(1);
printf("child2 create!/n");
signal(SIGINT,SIG_IGN); //触发相应软中断是不做任何处理
signal(17,int_func);//触发17号软中断时调用处理函数int_func()
waitting();
printf("child2 process is killed by parent!/n");
exit(0);
}
else
{
printf("parent create!/n");
sleep(1);
signal(SIGINT,int_func);
waitting();
kill(p1,16);
kill(p2,17);
wait(0);
wait(0);
printf("parent kill itself!/n");
exit(0);
}
}
return 0;
}
运行结果:
练习四 三个子进程和父进程的管道通信。
编写一个程序,建立一个管道。同时,父进程生成子进程P1,P2,P3,这三个子进程分别向管道中写入消息(消息由键盘输入),父进程将消息读出。
<code>
include<unistd.h>
#include<signal.h>
#include<stdio.h>
main()
{
int fd[2],p1,p2,p3;
char outpipe[100],inpipe[100];
pipe(fd); //创建管道
while((p1=fork())==-1); //创建子进程
if(p1==0)
{
lockf(fd[1],1,0); //锁定管道写入端
sprintf(outpipe,"child1 is send message!"); //定义发送缓冲区
write(fd[1],outpipe,50); //写入管道
sleep(1);
lockf(fd[1],0,0); //释放管道
exit(0); //子进程终止
}
else
{
while((p2=fork())==-1);
if(p2==0)
{
lockf(fd[1],1,0); //互斥
sprintf(outpipe,"child2 is send message!");
write(fd[1],outpipe,50);
sleep(1);
lockf(fd[1],0,0);
exit(0);
}
else
{
while((p3=fork())==-1);
if(p3==0)
{
lockf(fd[1],1,0);
sprintf(outpipe,"child3 is send message!");
write(fd[1],outpipe,50);
sleep(1);
lockf(fd[1],0,0);
exit(0);
}
else
{
wait(0); //同步 等待子进程终止
read(fd[0],inpipe,50);
printf("%s/n",inpipe);
wait(0); //同步 等待子进程终止
read(fd[0],inpipe,50);
printf("%s/n",inpipe);
wait(0); //同步 等待子进程终止
read(fd[0],inpipe,50);
printf("%s/n",inpipe);
exit(0);
}
}
}
}
运行结果:
练习五 利用消息的4个系统调用编写消息发送接收程序。
消息的创建、发送和接收。使用系统调用msgget( ),msgsnd( ),msgrev( ),及msgctl( )编制一长度为50字节的消息发送和接收的程序。
//client.c
#include<sys/msg.h>
#define MSGKEY 75
struct msgform
{ long mtype;
char mtext[256];
};
main()
{ struct msgform msg;
int msgqid,pid,*pint;
msgqid=msgget(MSGKEY,0777);
pid=getpid();
pint=(int *)msg.mtext;
*pint=pid;
msg.mtype=1;
msgsnd(msgqid,&msg,sizeof(int),0);
msgrcv(msgqid,&msg,256,pid,0);
printf("client:receive from pid%d/n",*pint);
}
//server.c
#include<sys/msg.h>
#define MSGKEY 75
struct msgform
{ long mtype; char mtext[256]; }msg;
int msgqid;
main()
{ int i,pid,*pint;
extern cleanup();
for(i=0;i<20;i++)
signal(i,cleanup);
msgqid=msgget(MSGKEY,0777|IPC_CREAT);
for(;;)
{ msgrcv(msgqid,&msg,256,1,0);
pint=(int *)msg.mtext;
pid=*pint;
printf("server:receive from pid %d/n",pid);
msg.mtype=pid;
msgsnd(msgqid,&msg,sizeof(int),0);
}
}
cleanup()
{ msgctl(msgqid,IPC_RMID,0); exit(); }
运行结果: