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

        }

}          

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值