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"); } } |