假期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;
}
相关推荐
云飞云共享云桌面44 分钟前
替代传统电脑的共享云服务器如何实现1拖8SolidWorks设计办公
linux·运维·服务器·网络·电脑·制造
RollingPin2 小时前
iOS八股文之 网络
网络·网络协议·ios·https·udp·tcp·ios面试
惘嘫、冋渞7 小时前
AWS同一账号下创建自定义VPC并配置不同区域的对等链接
网络·云计算·aws
云知谷8 小时前
【HTML】网络数据是如何渲染成HTML网页页面显示的
开发语言·网络·计算机网络·html
呉師傅13 小时前
关于联想ThinkCentre M950t-N000 M大师电脑恢复预装系统镜像遇到的一点问题
运维·网络·windows·电脑
代码AI弗森13 小时前
无状态的智慧:从 HTTP 到大模型的系统进化论
网络·网络协议·http
酷熊代理14 小时前
安卓手机 IP 切换指南:告别卡顿,轻松换 IP
网络·网络协议·tcp/ip·socks5
月上柳青14 小时前
快速创建无线AP热点
网络·智能路由器
K_i13415 小时前
云原生网络基础:IP、端口与网关实战
网络·ip·接口隔离原则
m0_6515939115 小时前
Netty网络架构与Reactor模式深度解析
网络·架构