CSAPP:异常控制流课后作业:交互打印pid

CSAPP:异常控制流课后作业:交互打印pid

编写程序,一个父进程p0,创建两个子进程p1和p2;要求只使用信号相关机制作为通信手段,让p1打印出p2的pid,p2打印出p1的pid

解题思路:

​ 总体思路是父进程掌握p1和p2的信息,让父进程给p2发送p1的信息,给p1发送p2的信息。但是只能发信号,不能发整数,所以只能一位一位的发,把pid_t 拆成32位发送。用两个信号 SIGUSR1SIGUSR2 分别代表该位是1和该位是0的信息发送,父进程每取了pid的一位就向子进程发送对应的信号,然后pause,子进程那边收到信号后会给父进程回一个信号,我这里用的是SIGCONT,父进程收到后pause解除,继续干活。。(如果不回信可能会因为异步导致信号被丢弃

​ 信息发送完了之后父进程发送SIGINT使子进程输出并终止就可以了

测试结果:

在这里插入图片描述
代码:

#include"csapp.h"
#include<signal.h>
#include<stdio.h>
#include<sys/types.h>

volatile int s1[8],s2[8];
volatile pid_t pid,p0,p1,p2;
volatile long ppid;               //pid of the other process
volatile int cnt;                 //count the bits
void handler_usr1(int sig)        // if one bit is 1 , SIGUSR1 sent
{
    sigset_t mask,prev_mask;
    Sigfillset(&mask);
    Sigprocmask(SIG_BLOCK,&mask,&prev_mask);
    ppid = (ppid | (1<<cnt));
    cnt++;
    Sigprocmask(SIG_SETMASK,&prev_mask,NULL);
    Kill(p0,SIGCONT);
}
void handler_usr2(int sig)        // if one bit is 0 , SIGUSR2 sent
{
    sigset_t mask,prev_mask;
    Sigfillset(&mask);
    Sigprocmask(SIG_BLOCK,&mask,&prev_mask);
    cnt++;
    Sigprocmask(SIG_SETMASK,&prev_mask,NULL);
    Kill(p0,SIGCONT);
}
void handler_sigint(int sig)      //prints and exit
{
    Sio_puts("process ");
    Sio_putl(pid);
    Sio_puts(" prints pid ");
    Sio_putl(ppid);
    Sio_puts("\n");
    _exit(0);
}

void handler_sigcont(int sig)      //send signal to father
{
    ;
}
int main()
{

    sigset_t mask,prev_mask;
    p0=getpid();
    cnt=0;
    ppid = 0;
    Sio_puts("The father's pid is: ");
    Sio_putl(p0);
    Sio_puts("\n");
    Signal(SIGUSR1,handler_usr1);
    Signal(SIGINT,handler_sigint);
    Signal(SIGUSR2,handler_usr2);
    Signal(SIGCONT,handler_sigcont);
    if((p1=fork())==0)
    {
        pid=getpid();
        while(1)
        ;
    }
    if((p2=fork())==0)
    {
        pid=getpid();
        while(1)
        ;
    }
    Sio_puts("p1 = ");
    Sio_putl(p1);
    Sio_puts("\n");
    Sio_puts("p2 = ");
    Sio_putl(p2);
    Sio_puts("\n");
    Sigfillset(&mask);
    for(int i=0;i<=31;i++)
    {
        if((p1>>i)&1)
        {
            Kill(p2,SIGUSR1);
            Pause();                //pause to wait children to update 
        }
        else
        {
            Kill(p2,SIGUSR2);
            Pause();                //pause to wait children to update
        }
        
    }
    for(int i=0;i<=31;i++)
    {
        if((p2>>i)&1)
        {
            Kill(p1,SIGUSR1);
            pause();
        }
        else
        {
            Kill(p1,SIGUSR2);
            Pause();
        }
    }
    Kill(p1,SIGINT);                // process p1 prints and exits
    Waitpid(-1,NULL,0);
    Kill(p2,SIGINT);                // process p2 prints and exits
    Waitpid(-1,NULL,0);
    Sio_puts("exit\n");             // main process exits
    _exit(0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值