linux进程间通信异步信号处理机制
Posted Henry Zheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux进程间通信异步信号处理机制相关的知识,希望对你有一定的参考价值。
linux实验报告9、10章
第九章 进程间通信(管道)
实验9-4
实现一个服务器和多个客户端之间的通信:
(1)服务器创建一个有名管道,供客户端写入信息.
(2)每个客户端为自己创建有名管道.供服务器写入信息.
(3)客户端打印出发送到服务器的信息,从服务器接受到的信息
题目分析:
使用MUFIFO作为命题管道,使用fopen函数打开对应的命名管道,然后将argv中的字符串写入该命名管道中.创建fifosend.c
与之前相类似,使用fopen函数打开命名为MYFIFO的管道文件,然后从其中读出对应的字符串并显示在屏幕上.创建fifoget.c
实验结果:
实验代码:
//fifosend.c
#include<stdio.h> #include<stdlib.h> #include<sys/types.h>
#define FIFO_FILE "MYFIFO"
int main(int argc, char *argv[])
FILE *fp; int i; if(argc<2)
printf("please use :%s<pathname>\\n", argv[0]); exit(1);
if((fp=fopen(FIFO_FILE,"w")) == NULL)
printf("fopen error!\\n"); exit(1);
for(i=1;i<argc;i++)
if(fputs(argv[i],fp) == EOF)
printf("write fifo error!\\n"); exit(1);
if(fputs("",fp) == EOF)
printf("write fifo error!\\n"); exit(1);
fclose(fp); return 0;
|
//fifoget.c
#include<stdio.h> #include<stdlib.h> #include<sys/stat.h> #include<unistd.h> #include<linux/stat.h> #include<errno.h>
#define FIFO_FILE "MYFIFO"
int main(int argc, char argv[])
FILE *fp; char readbuf[80];
if((fp=fopen(FIFO_FILE, "r")) == NULL)
umask(0); mknod(FIFO_FILE,S_IFIFO|0666,0);
else
fclose(fp);
while(1)
if((fp=fopen(FIFO_FILE, "r")) == NULL)
printf("open fifo error!\\n"); exit(1);
if(fgets(readbuf, 80, fp)!=NULL)
printf("get the readbuf is : %s\\n", readbuf); fclose(fp);
else
if(ferror(fp))
perror("read file error!\\n"); exit(1);
return 0;
|
第十章 异步信号处理机制
实验10-1
编写程序测试函数setitimer(int)和getitimer()。
安装信号, 使信号SIGALRM、SIGVTALRM、SIGPROF可以被捕获。
测试:setitimer()函数
运行结果:
实验代码:
//setitimer.c
#include<stdlib.h>
static void signalDeal(int signo)
struct timeval tp; struct tm *tm; gettimeofday(&tp,NULL); tm=localtime(&tp.tv_sec); system("clear"); printf("sec=%d\\t",tp.tv_sec); printf("usec=%d\\n",tp.tv_usec); printf("%d-%d-%d %d:%d:%d\\n",tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
static void InitTime(int tv_sec,int tv_usec)
struct itimerval value; signal(SIGALRM,signalDeal); value.it_value.tv_sec=tv_sec; value.it_value.tv_usec=tv_usec; value.it_interval.tv_sec=tv_sec; value.it_interval.tv_usec=tv_usec; setitimer(ITIMER_REAL,&value,NULL);
int main(int argc,char *argv[])
InitTime(1,0); while(1)
exit(0);
|
实验10-2
编写程序测试sigaction()函数。
sa_flags 设置为以下标志时,程序的行为有何不同。
对比程序运行情况予以说明。
SA_SIGINFO
SA_NOCLDSTOP
SA_NOCLDWAIT
SA_NODEFER
SA_RESETHAND
测试sigaction()函数
运行结果:
测试sigaction2()函数
运行结果:
函数代码:
//sigaction.c
#include<stdio.h> #include<stdlib.h> #include<signal.h>
void signalDeal(int sig,siginfo_t*info,void *t)
if(sig==SIGINT) //CTRL+C
printf("使用CTRL+C!\\n");
else if(sig==SIGQUIT) //CTRL+/
printf("使用CTRL+/!\\n");
else
printf("其他信号!\\n");
int main(int argc,char *argv[])
struct sigaction act; act.sa_sigaction = signalDeal; sigemptyset(&act.sa_mask); act.sa_flags=SA_SIGINFO; sigaction(SIGINT,&act,NULL); sigaction(SIGQUIT,&act,NULL); while(1)
return 0;
|
//sigaction2.c
#include <stdio.h> #include <unistd.h> #include <signal.h> #include <errno.h>
static void sig_usr(int signum)
if(signum == SIGUSR1)
printf("SIGUSR1 received\\n");
else if(signum == SIGUSR2)
printf("SIGUSR2 received\\n");
else
printf("signal %d received\\n", signum);
int main(void)
char buf[512]; int n; struct sigaction sa_usr; sa_usr.sa_flags = 0; sa_usr.sa_handler = sig_usr; //信号处理函数 sigaction(SIGUSR1, &sa_usr, NULL); sigaction(SIGUSR2, &sa_usr, NULL); printf("My PID is %d\\n", getpid()); while(1)
if((n = read(STDIN_FILENO, buf, 511)) == -1)
if(errno == EINTR)
printf("read is interrupted by signal\\n");
else
buf[n] = '\\0'; printf("%d bytes read: %s\\n", n, buf);
return 0;
|
测试sigprocmask()函数
运行结果:
实验代码:
//sigprocmask.c
#include <stdio.h> #include <unistd.h> #include <signal.h> #include <stdlib.h>
static void sig_quit(int signo)
printf("caught SIGQUIT\\n"); signal(SIGQUIT, SIG_DFL);//再次安装
int main()
sigset_t newmask, oldmask, pendmask;
signal(SIGQUIT, sig_quit);//安装信号处理函数
sigemptyset(&newmask);//初始化信号量集 sigaddset(&newmask, SIGQUIT);//将SIGQUIT添加到信号量集中
sigprocmask(SIG_BLOCK, &newmask, &oldmask);//将newmask中的SIGQUIT阻塞掉,并保存当前信号屏蔽字,原来值读到oldmask.
sleep (5);//休眠5秒钟
sigpending(&pendmask);//检查信号是否SIGQUIT被阻塞还没有被处理
if (sigismember(&pendmask, SIGQUIT))//SIGQUIT被阻塞还没有被处理
printf("\\nSIGQUIT pending\\n");
sigprocmask(SIG_SETMASK, &oldmask, NULL);//恢复被屏蔽的信号SIGQUIT
printf("SIGQUIT unblocked\\n");
sleep(5);//再次休眠5秒钟
return (0);
|
测试信号集
实验结果:
实验代码:
#include<signal.h> #include<stdio.h> #include<stdlib.h>
int output(sigset_t set);
int main()
sigset_t set; printf("after empty the set:\\n"); sigemptyset(&set); output(set);
printf("after add signo=7:\\n"); sigaddset(&set,7); output(set); printf("after add signo=13:\\n"); sigaddset(&set,13); output(set);
return 0;
int output(sigset_t set)
int i=0; for(i=0;i<1;i++)
printf("0x%8x\\n", set.__val[i]); if((i+1)%8==0) printf("\\n");
|
以上是关于linux进程间通信异步信号处理机制的主要内容,如果未能解决你的问题,请参考以下文章