队消息进程间通信

该代码示例展示了使用C语言通过消息队列进行进程间通信(IPC)的方法。两个进程分别创建线程,一个用于发送消息,另一个用于接收消息。消息结构包含类型和文本,支持'quit'命令退出程序。程序使用`msgget`、`msgsnd`、`msgrcv`等系统调用完成消息传递。

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

A代码

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<errno.h>

//创建消息包结构体
struct msgbuf
{
    long mtype;//消息类型,必须大于0
    char mtext[128];//消息队列信息大小和类型
};
int id,id1;
//接收消息字节数                                                                
ssize_t res=0;
//线程
void *call(void *arv)//arv=&snd
{    
    struct msgbuf snd=*(struct msgbuf*)arv;
    while(1)
    {
        /*printf("请输入类型:");
        scanf("%ld",&snd.mtype);
        getchar();*/
        printf("请输入>>>");
        bzero(snd.mtext,sizeof(snd.mtext));
        fgets(snd.mtext,sizeof(snd.mtext),stdin);//从流指针输入数据到数组
        snd.mtext[strlen(snd.mtext)-1]='\0';//将数组最后一位置为0
        //阻塞方式创建
        if(msgsnd(id,&snd,sizeof(snd.mtext),0)<0)
        {
            perror("msgsnd");
            break;
        }
        printf("消息发送成功\n");
        if(strcasecmp(snd.mtext,"quit")==0)                                  
        {
            printf("退出消息队列\n");
            break;
        }    

    }
    pthread_exit(NULL);//表示不输入状态值
}


int main(int argc, const char *argv[])
{
    //计算key值
    key_t key=ftok("./",1);
    if(key<0)
    {
        perror("ftok");
        return -1;
    }
    printf("key=%#x\n",key);
    //创建消息队列
    id=msgget(key,IPC_CREAT|0664);//成功返回消息队列id号 
    if(id<0)
    {
        perror("msgget");
        return -1;
    }
    //计算key1值
    key_t key1=ftok("./",2);
    if(key1<0)
    {
        perror("ftok");
        return -1;
    }
    printf("key1=%#x\n",key1);
    //创建消息队列key1
    id1=msgget(key1,IPC_CREAT|0664);//成功返回消息队列id号 
    if(id1<0)
    {
        perror("msgget");
        return -1;
    }
    printf("id1=%d\n",id);    
    //创建消息包
    struct msgbuf snd;//结构类型
    struct msgbuf rcv;//结构类型

    snd.mtype=1;

    //创建线程
    pthread_t pt;
    if(pthread_create(&pt,NULL,call,(void*)&snd)!=0)
    {
    perror("pthread_create");
    return -1;
    }
    while(1){    
        //阻塞方式读取消息队列中的消息,msgtyp=0,先进先出的原则
        res=msgrcv(id1,&rcv,sizeof(rcv.mtext),0,0);
        //非阻塞方式读取消息队列中的消息,msgtyp==0,先进先出的原则
        //res=msgrcv(id1,&rcv,sizeof(rcv.mtext),0,IPC_NOWAIT);
        if(res<0)
        {
            perror("msgrcv");
            break;//没有数据时退出循环        
        }
        printf("B说:res=%ld [%ld :%s]\n",res,rcv.mtype,rcv.mtext); 
        if(strcasecmp(rcv.mtext,"quit")==0)                                  
        {
            printf("退出消息队列\n");
            break;
        }
    }
    system("ipcs -q");
    pthread_join(pt,NULL);
    return 0;
}

目录

B代码


#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>

struct msgbuf
{
    long mtype;
    char mtext[128];
};
int id,id1;
//创建互斥锁
pthread_mutex_t mutex;
void *call(void *arv)
{
    struct msgbuf snd=*(struct msgbuf*)arv; 
    while(1)
    {
        /*printf("请输入类型:");
        scanf("%ld",&snd.mtype);
        getchar();*/
        fprintf(stdout,"请输入>>>");
        bzero(snd.mtext,sizeof(snd.mtext));
        fgets(snd.mtext,sizeof(snd.mtext),stdin);//从流指针输入数据到数组
        snd.mtext[strlen(snd.mtext)-1]='\0';//将数组最后一位置为0
        //阻塞方式创建

        if(msgsnd(id1,&snd,sizeof(snd.mtext),0)<0)
        {
            perror("msgsnd");
            break;
        }
        printf("消息发送成功\n");
        if(strcasecmp(snd.mtext,"quit")==0)
        {
            printf("退出消息队列\n");
            break;
        }
    }
    pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
    //计算key值
    key_t key=ftok("./",1);
    if(key<0)
    {
        perror("ftok");
        return -1;
    }
    printf("key=%#x\n",key);
    //创建消息队列
    id=msgget(key,IPC_CREAT|0664);
    if(id<0)
    {
        perror("msgget");
        return -1;
    }
    printf("id=%d\n",id);
    //计算key1值
    key_t key1=ftok("./",2);
    if(key1<0)
    {
        perror("ftok");
        return -1;
    }
    printf("key1=%#x\n",key1);
    //创建消息队列
    id1=msgget(key1,IPC_CREAT|0664);
    if(id1<0)
    {
        perror("msgget");
        return -1;
    }
    printf("id1=%d\n",id);
    //接收消息包                                                       
    struct msgbuf rcv;//结构类型
    ssize_t res=0;
    //创建消息包                                                                          
    struct msgbuf snd;//结构类型
    snd.mtype=12; 
    //创建线程                                                                                                  
    pthread_t pt;
    if(pthread_create(&pt,NULL,call,&snd)!=0)
    {
        perror("pthread_create");
        return -1;
    }

    while(1){    
        res=msgrcv(id,&rcv,sizeof(rcv.mtext),0,0);
        if(res<0)
        {
            break;//没有数据时退出循环
        }
        printf("A进程说res=%ld [%ld :%s]\n",res,rcv.mtype,rcv.mtext);
        if(strcasecmp(rcv.mtext,"quit")==0)
        {
            printf("退出消息队列\n");
            break;
        } 
    }
    system("ipcs -q");
    pthread_join(pt,NULL);

    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值