假期day3,三种进程间通信代码实现(2024/2/4)

消息队列

c 复制代码
#include<myhead.h>
struct msgbuf{
    long mstype;
    char text[1024];
};

#define SIZE (sizeof(struct msgbuf)-sizeof(long))

int main(int argc, const char *argv[])
{

    int pid;

    //创建key值
    key_t key=ftok("/",'a');
    if(key ==-1){
        perror("creat key");
        return -1;
    }
    printf("key=%d\n",key);

    //创建消息队列
    int msgid=msgget(key,IPC_CREAT|0664);
    if(msgid==-1){
        perror("msgget");
        return -1;
    }

    struct msgbuf msg;

    pid=fork();
    if(pid>0)//父进程完成写入操作
    {
        while(1)
        {
            //写类型10的数据
            printf("请输入数据类型\n");
            scanf("%ld",&msg.mstype);
            printf("请输入数据\n");
            scanf("%s",msg.text);

            msgsnd(msgid,&msg,SIZE,0);
            if(strcmp(msg.text,"quit")==0)break;


        //删除消息队列
        if(msgctl(msgid,IPC_RMID,NULL)==-1){
            perror("msgctl error");
            return -1;
        }
        printf("删除完成\n");

    }else if(pid==0)//子进程完成读取操作
    {
        while(1)
        {
            msgrcv(msgid,&msg,SIZE,5,0);//读类型5的数据
            printf("收到信息:\n");
            printf("id=%ld,text=%s\n",msg.mstype,msg.text);
            if(strcmp(msg.text,"quit")==0)break;
        }
        exit(0);
    }else{
        perror("create pid");
        return -1;
    }
    
    wait(NULL);
    
    return 0;
}  
c 复制代码
#include<myhead.h>
struct msgbuf{
    long mstype;
    char text[1024];
};

#define SIZE (sizeof(struct msgbuf)-sizeof(long))

int main(int argc, const char *argv[])
{

    int pid;

    //创建key值
    key_t key=ftok("/",'a');
    if(key ==-1){
        perror("creat key");
        return -1;
    }
    printf("key=%d\n",key);

    //创建消息队列
    int msgid=msgget(key,IPC_CREAT|0664);
    if(msgid==-1){
        perror("msgget");
        return -1;
    }

    struct msgbuf msg;

    pid=fork();
    if(pid>0)//父进程完成写入操作
    {
        while(1)
        {
            //写类型5的数据
            printf("请输入数据类型\n");
            scanf("%ld",&msg.mstype);
            printf("请输入数据\n");
            scanf("%s",msg.text);

            msgsnd(msgid,&msg,SIZE,0);
            if(strcmp(msg.text,"quit")==0)break;
        }

        //删除消息队列
        if(msgctl(msgid,IPC_RMID,NULL)==-1){
            perror("msgctl error");
            return -1;
        }
        printf("删除完成\n");

    }else if(pid==0)//子进程完成读取操作
    {
        while(1)
        {
            msgrcv(msgid,&msg,SIZE,10,0);//读类型10的数据
            printf("收到信息:\n");
            printf("id=%ld,text=%s\n",msg.mstype,msg.text);
            if(strcmp(msg.text,"quit")==0)break;
        }
        exit(0);
    }else{
        perror("create pid");
        return -1;
    }

    wait(NULL);

    return 0;
}  

有名管道进程间通信

c 复制代码
半双工相互通信
#include<myhead.h>

//发送方线程
void* task1(void* arg){
    //创建管道文件
    if((mkfifo("myfifo",0664)) == -1){
        perror("mkfile error");
    }

    //打开管道描述符
    int wfd=-1;
    if((wfd=open("myfifo",O_WRONLY))==-1){
        perror("open write");
    }

    printf("输入quit为退出会话\n");

    char wbuf[128]="";
    while(1){
        printf("请输入您要发送的信息:\n");
        fgets(wbuf,sizeof(wbuf),stdin);
        wbuf[strlen(wbuf)-1]=0;

        write(wfd,wbuf,sizeof(wbuf));
        if(strcmp(wbuf,"quit")==0)
        {
            break;
        }
    }
    close(wfd);
    system("rm myfifo");

    pthread_exit(NULL);
}

//接收方线程
void* task2(void* arg){
    int rfd=-1;
    if((rfd=open("myfifo",O_RDONLY))==-1){
        perror("read error");
    }

    char rbuf[128]="";
    while(1){
        memset(rbuf,0,sizeof(rbuf));
        read(rfd,rbuf,sizeof(rbuf));
        printf("您收到一条信息:%s\n",rbuf);
        if(strcmp(rbuf,"quit")==0){
            break;
        }
    }
    close(rfd);
    pthread_exit(NULL);
}


int main(int argc, const char *argv[])
{
    //定义两个线程
    pthread_t tid1,tid2;
    int flag;
    while(1)
    {
        printf("------------------会话只能由发送方发起与结束--------------\n");
        printf("-----------------------选择1:发送信息-------------------\n");
        printf("-----------------------选择2:接收信息-------------------\n");
        printf("-------------------------选择0:退出---------------------\n");
        scanf("%d",&flag);
        switch(flag)
        {
            case 1:
                //线程一
                if((pthread_create(&tid1,NULL,task1,NULL)) !=0)
                {
                    printf("tid1 create error\n");
                    return -1;
                }
                pthread_join(tid1,NULL);
                break;
            case 2:
                //线程二
                if((pthread_create(&tid2,NULL,task2,NULL)) !=0)
                {
                    printf("tid1 create error\n");
                    return -1;
                }
                pthread_join(tid2,NULL);
                break;
            case 0:
                goto END;
        }
        printf("输入'#'字符结束,否则继续\n");
        char element;
        element=getchar();
        if(element == '#')break;
    }
END:
    return 0;
}   

无名管道

c 复制代码
#include<myhead.h>

int main(int argc, const char *argv[])
{
    //定义进程号变量
    pid_t pid = -1;
    //定义存放管道文件描述符的数组
    int pipefd[2] = {0};

    //创建管道文件
    if(pipe(pipefd) == -1)
    {
        perror("pipe error");
        return -1;
    }

    printf("pipefd[0] = %d, pipefd[1] = %d\n", pipefd[0], pipefd[1]); //3 4




    //创建一个子进程
    pid = fork();
    if(pid > 0)
    {
        //父进程
        //关闭父进程中管道的读端
        close(pipefd[0]);

        char buf[128] = "";
        while(1)
        {
            //从终端上获取数据放入buf中
            fgets(buf, sizeof(buf), stdin);
            buf[strlen(buf)-1] = 0;          //将'\n'换成'\0'

            write(pipefd[1], buf, sizeof(buf));         //将数据写入管道文件中

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


        //关闭写端
        close(pipefd[1]);


    }else if(pid == 0)
    {
        //子进程
        //子进程关闭管道的写端
        close(pipefd[1]);

        char rbuf[128] = "";
        while(1)
        {
            bzero(rbuf, sizeof(rbuf));    //将数组内容置0

            read(pipefd[0], rbuf, sizeof(rbuf));           //从管道文件中读取数据

            printf("收到父进程消息: %s\n", rbuf);             //hello  world

            if(strcmp(rbuf, "quit") == 0)
            {
                break;
            }
        }

        //关闭读端
        close(pipefd[0]);


        //退出子进程
        exit(EXIT_SUCCESS);
    }else
    {
        perror("fork error");
        return -1;
    }
    
    //父进程回收子进程的资源
    wait(NULL);

    return 0;
}
相关推荐
hzyyyyyyyu1 小时前
内网安全隧道搭建-ngrok-frp-nps-sapp
服务器·网络·安全
刽子手发艺2 小时前
WebSocket详解、WebSocket入门案例
网络·websocket·网络协议
速盾cdn6 小时前
速盾:CDN是否支持屏蔽IP?
网络·网络协议·tcp/ip
yaoxin5211236 小时前
第二十七章 TCP 客户端 服务器通信 - 连接管理
服务器·网络·tcp/ip
内核程序员kevin6 小时前
TCP Listen 队列详解与优化指南
linux·网络·tcp/ip
PersistJiao7 小时前
Spark 分布式计算中网络传输和序列化的关系(一)
大数据·网络·spark
黑客Ash10 小时前
【D01】网络安全概论
网络·安全·web安全·php
->yjy10 小时前
计算机网络(第一章)
网络·计算机网络·php
摘星星ʕ•̫͡•ʔ11 小时前
计算机网络 第三章:数据链路层(关于争用期的超详细内容)
网络·计算机网络