IO-day(8)-(进程间的通信方式(有/无管道)、信号集)

本文展示了使用有名管道(FIFO)实现AB两个进程之间的通信,进程A先发送信息给B,B接收到后回复,直到收到quit才结束。同时,程序还捕获了2(SIGINT)、3和20号信号。附加题中,通过线程实现了进程A和B的并发收发功能。
摘要由CSDN通过智能技术生成

作业一、
1.要求实现AB进程对话
A进程先发送一句话给B进程,B进程接收后打印
B进程再回复一句话给A进程,A进程接收后打印
重复1.2步骤,当收到quit后,要结束AB进程
提示:两根管道

myfifo_w

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, const char *argv[])
{
    umask(0);
    // 创建有名管道
    if (mkfifo("./myfifo_a", 0777) < 0)
    {
        // 文件已经存在是一个合法错误,需要排除,代码允许正常运行
        if (17 != errno)
        {
            perror("mkfifo");
            return -1;
        }

        printf("myfifo success\n");
    }

    if (mkfifo("./myfifo_b", 0777) < 0)
    {
        // 文件已经存在是一个合法错误,需要排除,代码允许正常运行
        if (17 != errno)
        {
            perror("mkfifo");
            return -1;
        }

        printf("myfifo success\n");
    }

    // 有名管道存在,则直接读写管道

    int fd_a = open("./myfifo_a", O_WRONLY);
    if (fd_a < 0)
    {
        perror("open");
        return -1;
    }
    printf("open success a\n");

    int fd_b = open("./myfifo_b", O_RDONLY);
    if (fd_b < 0)
    {
        perror("open");
        return -1;
    }
    printf("open success b\n");

    char buf[128] = "";
    char talk[128] = "";
    ssize_t res_talk = 0;
    while (1)
    {

        printf("A:");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = 0;
        if (write(fd_a, buf, sizeof(buf)) < 0)
        {
            perror("write");
            return -1;
        }

        //*********************************************

        bzero(talk, sizeof(talk));
        res_talk = read(fd_b, talk, sizeof(talk));
        if (res_talk < 0)
        {
            perror("read");
            return -1;
        }
        else if (0 == res_talk)
        {
            printf("写端退出\n");
            break;
        }
        fprintf(stderr, "B:%s\n", talk);

        //**********************************************
        if (strcmp(buf, "quit") == 0 || strcmp(talk, "quit") == 0)
        {
            break;
        }
    }

    close(fd_a);
    close(fd_b);

    return 0;
}

myfifo_r

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, const char *argv[])
{
    umask(0);
    // 创建有名管道
    if (mkfifo("./myfifo", 0777) < 0)
    {
        // 文件已经存在是一个合法错误,需要排除,代码允许正常运行
        if (17 != errno)
        {
            perror("mkfifo");
            return -1;
        }

        printf("myfifo success\n");
    }

    if (mkfifo("./myfifo_b", 0777) < 0)
    {
        // 文件已经存在是一个合法错误,需要排除,代码允许正常运行
        if (17 != errno)
        {
            perror("mkfifo");
            return -1;
        }

        printf("myfifo success\n");
    }

    // 有名管道存在,则直接读写管道

    int fd_a = open("./myfifo_a", O_RDONLY);
    if (fd_a < 0)
    {
        perror("open");
        return -1;
    }
    printf("open success a\n");

    int fd_b = open("./myfifo_b", O_WRONLY);
    if (fd_b < 0)
    {
        perror("open");
        return -1;
    }
    printf("open success b\n");

    char buf[128] = "";
    char talk[128] = "";
    ssize_t res = 0;

    while (1)
    {

        bzero(buf, sizeof(buf));
        res = read(fd_a, buf, sizeof(buf));
        if (res < 0)
        {
            perror("read");
            return -1;
        }
        else if (0 == res)
        {
            printf("写端退出\n");
            break;
        }
        fprintf(stderr, "A:%s\n", buf);

        //**************************************************

        printf("B:");
        fgets(talk, sizeof(talk), stdin);
        talk[strlen(talk) - 1] = 0;
        if (write(fd_b, talk, sizeof(talk)) < 0)
        {
            perror("write");
            return -1;
        }
        
        //**********************************************

        if (strcmp(buf, "quit") == 0 || strcmp(talk, "quit") == 0)
        {
            break;
        }
    }
    

    close(fd_a);
    close(fd_b);

    return 0;
}

结果:

 作业、

捕获2 3 20号信号

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

typedef void (*sighandler_t)(int);

void handler(int sig)
{
    printf("触发sig=%d信号\n", sig);
}

int main(int argc, const char *argv[])
{
    // 捕获信号2,SIGINT,注册新的处理函数
    __sighandler_t s1 = signal(2, handler);
    if (SIG_ERR == s1)
    {
        perror("signal");
        return -1;
    }

    __sighandler_t s2 = signal(3, handler);
    if (SIG_ERR == s2)
    {
        perror("signal");
        return -1;
    }

    __sighandler_t s3 = signal(20, handler);
    if (SIG_ERR == s3)
    {
        perror("signal");
        return -1;
    }

    while (1)
    {
        printf("signal......\n");
        sleep(1);
    }
    return 0;
}

结果:

作业三、附加题:在第1题的基础上,能够实现随时收发

myfifo_w

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

char buf[128] = "";
char talk[128] = "";
ssize_t res_talk = 0;

struct date
{
    int fd_a;
    int fd_b;
};

void *my_buf(void *arg)
{
    int fd_a = ((struct date *)arg)->fd_a;
    while (1)
    {
        printf("A:");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = 0;
        if (write(fd_a, buf, sizeof(buf)) < 0)
        {
            perror("write");
            return NULL;
        }

        if (strcmp(buf, "quit") == 0 || strcmp(talk, "quit") == 0)
        {
            break;
        }
    }
   
    pthread_exit(NULL);
}

void *my_talk(void *arg)
{
    int fd_b = ((struct date *)arg)->fd_b;

    while (1)
    {
        bzero(talk, sizeof(talk));
        res_talk = read(fd_b, talk, sizeof(talk));
        if (res_talk < 0)
        {
            perror("read");
            return NULL;
        }
        else if (0 == res_talk)
        {
            printf("写端退出\n");
            break;
        }
        fprintf(stderr, "B:%s\n", talk);

        if (strcmp(buf, "quit") == 0 || strcmp(talk, "quit") == 0)
        {
            break;
        }
    }
    
    pthread_exit(NULL);
}

int main(int argc, const char *argv[])
{
    umask(0);
    // 创建有名管道
    if (mkfifo("./myfifo_a", 0777) < 0)
    {
        // 文件已经存在是一个合法错误,需要排除,代码允许正常运行
        if (17 != errno)
        {
            perror("mkfifo");
            return -1;
        }

        printf("myfifo success\n");
    }

    if (mkfifo("./myfifo_b", 0777) < 0)
    {
        // 文件已经存在是一个合法错误,需要排除,代码允许正常运行
        if (17 != errno)
        {
            perror("mkfifo");
            return -1;
        }

        printf("myfifo success\n");
    }

    // 有名管道存在,则直接读写管道

    int fd_a = open("./myfifo_a", O_WRONLY);
    if (fd_a < 0)
    {
        perror("open");
        return -1;
    }
    printf("open success a\n");

    int fd_b = open("./myfifo_b", O_RDONLY);
    if (fd_b < 0)
    {
        perror("open");
        return -1;
    }
    printf("open success b\n");

    struct date info;
    info.fd_a = fd_a;
    info.fd_b = fd_b;

    pthread_t tid1, tid2;
    if (pthread_create(&tid1, NULL, my_buf, &info) != 0)
    {
        printf("filed__%d__\n", __LINE__);
        return -1;
    }
    
    pthread_detach(tid1);

    if (pthread_create(&tid2, NULL, my_talk, &info) != 0)
    {
        printf("filed__%d__\n", __LINE__);
        return -1;
    }

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    

    close(fd_a);
    close(fd_b);

    return 0;
}

myfifo_r

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

char buf[128] = "";
char talk[128] = "";
ssize_t res = 0;

struct date
{
    int fd_a;
    int fd_b;
};

void *my_buf(void *arg)
{
    int fd_a = ((struct date *)arg)->fd_a;
    while (1)
    {
        bzero(buf, sizeof(buf));
        res = read(fd_a, buf, sizeof(buf));
        if (res < 0)
        {
            perror("read");
            return NULL;
        }
        else if (0 == res)
        {
            printf("写端退出\n");
            break;
        }
        fprintf(stderr, "A:%s\n", buf);

        if (strcmp(buf, "quit") == 0 || strcmp(talk, "quit") == 0)
        {
            break;
        }
    }
    

    pthread_exit(NULL);
}

void *my_talk(void *arg)
{
    int fd_b = ((struct date *)arg)->fd_b;

    while (1)
    {
        printf("B:");
        fgets(talk, sizeof(talk), stdin);
        talk[strlen(talk) - 1] = 0;
        if (write(fd_b, talk, sizeof(talk)) < 0)
        {
            perror("write");
            return NULL;
        }

        if (strcmp(buf, "quit") == 0 || strcmp(talk, "quit") == 0)
        {
            break;
        }
    }
    
    pthread_exit(NULL);
}

int main(int argc, const char *argv[])
{
    umask(0);
    // 创建有名管道
    if (mkfifo("./myfifo", 0777) < 0)
    {
        // 文件已经存在是一个合法错误,需要排除,代码允许正常运行
        if (17 != errno)
        {
            perror("mkfifo");
            return -1;
        }

        printf("myfifo success\n");
    }

    if (mkfifo("./myfifo_b", 0777) < 0)
    {
        // 文件已经存在是一个合法错误,需要排除,代码允许正常运行
        if (17 != errno)
        {
            perror("mkfifo");
            return -1;
        }

        printf("myfifo success\n");
    }

    // 有名管道存在,则直接读写管道

    int fd_a = open("./myfifo_a", O_RDONLY);
    if (fd_a < 0)
    {
        perror("open");
        return -1;
    }
    printf("open success a\n");

    int fd_b = open("./myfifo_b", O_WRONLY);
    if (fd_b < 0)
    {
        perror("open");
        return -1;
    }
    printf("open success b\n");

    struct date info;
    info.fd_a = fd_a;
    info.fd_b = fd_b;

    pthread_t tid1, tid2;
    if (pthread_create(&tid1, NULL, my_buf, &info) != 0)
    {
        printf("filed__%d__\n", __LINE__);
        return -1;
    }

    pthread_detach(tid1);

    if (pthread_create(&tid2, NULL, my_talk, &info) != 0)
    {
        printf("filed__%d__\n", __LINE__);
        return -1;
    }

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    
    close(fd_a);
    close(fd_b);

    return 0;
}

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值