8月4日 IO进程线程作业

这段代码展示了如何使用有名管道(FIFO)实现在两个进程间交替发送和接收消息,直到接收到特定退出指令'quit'。附加题中通过fork创建子进程,实现了进程可以随时收发数据的功能。此外,还演示了捕获2号(SIGINT)、3号(SIGQUIT)和20号(SIGTSTP)信号并自定义处理函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1)要求AB进程做通信
1. A进程发送一句话,B进程接收打印
2. 然后B进程发送给A进程一句话,A进程接收打印
3. 重复1,2步骤,直到A进程或者B进程收到quit,退出AB进程;


   

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    if(argc < 3)
    {
        printf("请正确输入你需要创建的管道文件名\n");
        return -1;
    }
    umask(0);   //修改文件权限掩码
    if(mkfifo(argv[1],0664) < 0)  //创造第一个有名管道
    {
        if(errno != 17)
        {
            perror("mkfifo");
            return -1;
        }
    }
    if(mkfifo(argv[2],0664) < 0)  //创造第二个有名管道
    {
        if(errno != 17)
        if(strcasecmp(str,"quit"))
            break;
        {
            perror("mkfifo");
            return -1;
        }
    }
    int fd1 = open(argv[1],O_WRONLY);   //以只写的方式打开第一个管道文件
    int fd2 = open(argv[2],O_RDONLY);   //以只读的方式打开第二个管道文件
    char str[128] = "";                 //存放要写的数据
    char buf[128] = "";                 //存放要读的数据
    ssize_t res = 0;                    //记录读到的个数
    while(1)
    {                                   //先往第一个管道文件里写数据
        printf("请输入>>");
        fgets(str,sizeof(str),stdin);
        str[strlen(str)-1] = '\0';
        if(write(fd1,str,sizeof(str)) < 0)
        {
            perror("write");
            return -1;                                                       
        }
        if(strcasecmp(str,"quit") == 0)
            break;

        bzero(buf,sizeof(buf));        //再从第二个管道文件里读数据
        res = read(fd2,buf,sizeof(buf));
        if(strcasecmp(buf,"quit") == 0)
            break;
        printf("对方说:%s\n",buf);
        if(res < 0)
        {
            perror("read");
            return -1;
        }else if(0 == res)
        {
            printf("对方进程退出\n");
            break;
        }

    }
    close(fd1);   //关闭第一个文件
    close(fd2);   //关闭第二个文件



    return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    if(argc < 3)
    {
        printf("请正确输入你需要创建的管道文件名\n");
        return -1;
    }
    umask(0);   //修改文件权限掩码
    if(mkfifo(argv[1],0664) < 0)  //创造第一个有名管道
    {
        if(errno != 17)
        {
            perror("mkfifo");
            return -1;
        }
    }
    if(mkfifo(argv[2],0664) < 0)  //创造第二个有名管道
    {
        if(errno != 17)
        {
            perror("mkfifo");
            return -1;
        }
    }
    int fd1 = open(argv[1],O_RDONLY);   //以只读的方式打开第一个管道文件
    int fd2 = open(argv[2],O_WRONLY);   //以只写的方式打开第二个管道文件
    char buf[128] = "";                 //存放读到的数据
    char str[128] = "";                 //存放要写的数据
    ssize_t res = 0;                    //记录读到的个数
    while(1)
    {
        bzero(buf,sizeof(buf));        //先从第一个管道文件里读数据
        res = read(fd1,buf,sizeof(buf));
        if(strcasecmp(buf,"quit") == 0)
            break;
        printf("对方说:%s\n",buf);
        if(res < 0)
        {
            perror("read");
            return -1;
        }else if(0 == res)
        {
            printf("对方进程退出\n");
            break;
        }

        printf("请输入>>");              //再往第二个管道文件里写数据
        fgets(str,sizeof(str),stdin);
        str[strlen(str)-1] = '\0';
        if(write(fd2,str,sizeof(str)) < 0)
        {
            perror("write");
            return -1;
        }
        if(strcasecmp(str,"quit") == 0)
            break;


    }
    close(fd1);      //关闭第一个文件
    close(fd2);      //关闭第二个文件 



    return 0;
}                                                                            

 

2)在第一题的基础上实现,AB进程能够随时收发数据(附加题)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    if(argc < 3)
    {
        printf("请正确输入你需要创建的管道文件名\n");
        return -1;
    }
    umask(0);   //修改文件权限掩码
    if(mkfifo(argv[1],0664) < 0)  //创造第一个有名管道
    {
        if(errno != 17)
        {
            perror("mkfifo");
            return -1;
        }
    }
    if(mkfifo(argv[2],0664) < 0)  //创造第二个有名管道
    {
        if(errno != 17)
        {
            perror("mkfifo");
            return -1;
        }
    }
    int fd1 = open(argv[1],O_WRONLY);   //以只写的方式打开第一个管道文件
    int fd2 = open(argv[2],O_RDONLY);   //以只读的方式打开第二个管道文件
    char str[128] = "";                 //存放要写的数据
    char buf[128] = "";                 //存放要读的数据
    ssize_t res = 0;                    //记录读到的个数
    pid_t tid = fork();
    if(tid > 0)                         //说明在主线程
    {
        while(1)
        {                                   //先往第一个管道文件里写数据
            printf("请输入>>");
            fgets(str,sizeof(str),stdin);
            str[strlen(str)-1] = '\0';
            if(write(fd1,str,sizeof(str)) < 0)
            {
                perror("write");
                return -1;
            }
            if(strcasecmp(str,"quit") == 0)
                break;
        }


    }
    if(0 == tid)
    {
        while(1)
        {
            bzero(buf,sizeof(buf));        //再从第二个管道文件里读数据
            res = read(fd2,buf,sizeof(buf));
            if(strcasecmp(buf,"quit") == 0)                                   
                break;
            printf("对方说:%s\n",buf);
            if(res < 0)
            {
                perror("read");
                return -1;
            }else if(0 == res)
            {
                printf("对方进程退出\n");
                exit(0);
            }
        }

    }
    close(fd1);   //关闭第一个文件
    close(fd2);   //关闭第二个文件



    return 0;
}
                                                                              
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    if(argc < 3)
    {
        printf("请正确输入你需要创建的管道文件名\n");
        return -1;
    }
    umask(0);   //修改文件权限掩码
    if(mkfifo(argv[1],0664) < 0)  //创造第一个有名管道
    {
        if(errno != 17)
        {
            perror("mkfifo");
            return -1;
        }
    }
    if(mkfifo(argv[2],0664) < 0)  //创造第二个有名管道
    {
        if(errno != 17)
        {
            perror("mkfifo");
            return -1;
        }
    }
    int fd1 = open(argv[1],O_RDONLY);   //以只读的方式打开第一个管道文件
    int fd2 = open(argv[2],O_WRONLY);   //以只写的方式打开第二个管道文件
    char buf[128] = "";                 //存放读到的数据
    char str[128] = "";                 //存放要写的数据
    ssize_t res = 0;                    //记录读到的个数
    pid_t tid = fork();
    if(tid > 0)
    {
        while(1)
        {
            bzero(buf,sizeof(buf));        //先从第一个管道文件里读数据
            res = read(fd1,buf,sizeof(buf));
            if(strcasecmp(buf,"quit") == 0)
                break;
            printf("对方说:%s\n",buf);
            if(res < 0)
            {
                perror("read");
                return -1;
            }else if(0 == res)
            {
                printf("对方进程退出\n");
                break;
            }
        }
    }
    if(0 == tid)
    {
        while(1)
        {
            printf("请输入>>");              //再往第二个管道文件里写数据
            fgets(str,sizeof(str),stdin);
            str[strlen(str)-1] = '\0';
            if(write(fd2,str,sizeof(str)) < 0)                                                  
            {
                perror("write");
                return -1;
            }
            if(strcasecmp(str,"quit") == 0)
                exit(0);
        }

    }
    close(fd1);      //关闭第一个文件
    close(fd2);      //关闭第二个文件 



    return 0;
}

3)捕获2)3)20)号信号 

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
typedef void (*sighandler_t)(int);
void handler1(int sig);                     //2号信号新的处理函数
void handler2(int sig);                     //3号信号新的处理函数
void handler3(int sig);                     //20号信号新的处理函数
int main(int argc, const char *argv[])
{
    printf("h1:%p h2:%p h3:%p\n",handler1,handler2,handler3);
    sighandler_t s1 = signal(2,handler1);   //捕捉2号信号SIGINT
    if(s1 == SIG_ERR)
    {
        perror("signal");
        return -1;
    }
    sighandler_t s2 = signal(3,handler2);   //捕捉3号信号SIGQUIT

    if(s2 == SIG_ERR)
    {
        perror("signal");
        return -1;
    }
    sighandler_t s3 = signal(20,handler3);   //捕捉20号信号SIGTSTP

    if(s3 == SIG_ERR)
    {
        perror("signal");
        return -1;                                                                 
    }

    while(1)
    {
        printf("this is man\n");
        sleep(1);
    }

    return 0;
}
void handler1(int sig)                      //2号信号新的处理函数
{
    printf("这是handler1 是%d号信号\n",sig);

}

void handler2(int sig)                     //3号信号新的处理函数
{
    printf("这是handler2 是%d号信号\n",sig);

}

void handler3(int sig)                     //20号信号新的处理函数
{
    printf("这是handler3 是%d号信号\n",sig);

}
                                                                                   

 

 

 



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值