简单的使用消息队列的多线程通信

下面是简单的两个进程的通信,简称server.c   和 client.c

server.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#define SIZE 256
using namespace std;
struct msg{
    long mtype;
    char text[SIZE];
};
pthread_t sendtid,recvtid;
void* serverSend(void* arg)
{
    int msgid =(int)arg;
    sendtid = pthread_self();//获取线程号
    char buf[SIZE];
    struct msg ms;
    while(1){
        memset(buf,0,sizeof(buf));
        cout<<"input <<<<<<< :";
        fgets(buf,SIZE,stdin);
        buf[strlen(buf)-1] ='\0';
        strcpy(ms.text,buf);
        ms.mtype = 1;          //发送类型为1    
        if( !strcmp(buf,"quit")){ //如果输入quit   break
     		 if(msgsnd(msgid,&ms,strlen(ms.text),0) < 0){
           		 perror("failed to send message");
          	  	 exit(-1);
       		 }
		break;
	} 

        if(msgsnd(msgid,&ms,strlen(ms.text),0) < 0){
            perror("failed to send message");
            exit(-1);
        }
    }
    pthread_cancel(recvtid);    //终止接收线程
    return ((void*)1);
}
void* clientRecv(void *arg)
{
    int msgid =(int)arg;
    recvtid = pthread_self();//获取线程号
    struct msg ms;
    while(1){
        memset(&ms,0,sizeof(ms));
        if(msgrcv(msgid,&ms,sizeof(ms.text),2,0) < 0){
            perror("failed to get message");
	    pthread_cancel(sendtid);  
            exit(-1);
        }	
	if(!strcmp(ms.text,"quit")){           //如果收到quit   break
		break;
	}
       	printf("\routput------>%s\n",ms.text);
	printf("input------<");
	fflush(stdout);
    }
    pthread_cancel(sendtid);     //终止发送线程
    return ((void*)1);
}
int getMessQueueId()
{
    key_t key;
    int msg_id;
    if((key = ftok(".",'a')) < 0){
        perror("failed to get key");
        exit(-1);
    }
    if( (msg_id = msgget(key,0666 | IPC_CREAT)) < 0){
        perror("failed to get msid");
        exit(-1);
    }
    return msg_id;
}
int main()
{
    pthread_t tid1;
    pthread_t tid2;
    int msgid = getMessQueueId();
    int err;
    void *arg =(void *)msgid;
    err = pthread_create(&tid1,NULL,serverSend,arg);
    if(err != 0)
    {
        cout<<"error"<<endl;
        exit(-1);
    }
    err = pthread_create(&tid2,NULL,clientRecv,arg);
    err = pthread_join(tid1,NULL);    
    if(err != 0)
    {
        cout<<"error"<<endl;
        exit(-1);
    }
    err = pthread_join(tid2,NULL);
    if(err != 0)
    {
        cout<<"error"<<endl;
        exit(-1);
    }
    char tempbuf[20];
    sprintf(tempbuf,"ipcrm -q %d",msgid);    //删除消息标识符     
    system(tempbuf);

    return 0;
}


client.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#define SIZE 256
using namespace std;
struct msg{
    long mtype;
    char text[SIZE];
};

pthread_t sendtid,recvtid;
 void  killAnotherthread(pthread_t tid)
{
    if(pthread_kill(tid,0) != ESRCH)           //kill发送线程
	{
		cout<<"thread exist"<<endl;
		pthread_kill(tid,SIGQUIT);
		cout<<"after kill"<<endl;
	}
}
void* serverSend(void* arg)
{
    int msgid =(int)arg;
    sendtid = pthread_self();         //获取线程号
    //fprintf(stdout,"msgid = %d\n",msgid);
    char buf[SIZE];
    struct msg ms;
    while(1){
        memset(buf,0,sizeof(buf));
	cout<<"input <<<<<<< :";
        fgets(buf,SIZE,stdin);
        buf[strlen(buf)-1] ='\0';
        strcpy(ms.text,buf);
        ms.mtype = 2;          //发送类型为2
        if( !strcmp(buf,"quit")) {    //如果输入quit   break
	  if(msgsnd(msgid,&ms,strlen(ms.text),0) < 0){
              perror("failed to send message");
              exit(-1);
       	   }
	   break;
	}

        if(msgsnd(msgid,&ms,strlen(ms.text),0) < 0){
            perror("failed to send message");
            exit(-1);
        }
    } 
	
    killAnotherthread(recvtid);   //  kill  接收线程
    return ((void*)1);
}
void* clientRecv(void *arg)
{
    int msgid =(int)arg;
    recvtid = pthread_self();//获取线程号
    //fprintf(stdout,"msgid = %d\n",msgid);
    struct msg ms;
    while(1){
        memset(&ms,0,sizeof(ms));
        if(msgrcv(msgid,&ms,sizeof(ms.text),1,0) < 0){
            perror("failed to get message");	    
            exit(-1);
        }
	if( !strcmp(ms.text,"quit")){
		break;
	}
	printf("\r output------>%s\n",ms.text);
	printf("input------<");
	fflush(stdout);
    }
     killAnotherthread(sendtid);     //kill发送线程
	
    return ((void*)1);
}


int getMessQueueId()
{
    key_t key;
    int msg_id;
    if((key = ftok(".",'a')) < 0){
        perror("failed to get key");
        exit(-1);
    }
    if( (msg_id = msgget(key,0666 | IPC_CREAT)) < 0){
        perror("failed to get msid");
        exit(-1);
    }
    return msg_id;
}
int main()
{
    pthread_t tid1;
    pthread_t tid2;
    int msgid = getMessQueueId();
    int err;
    void *arg =(void *)msgid;
    err = pthread_create(&tid1,NULL,serverSend,arg);
    //fprintf(stdout,"tid1 = %d\n",tid1);
    if(err != 0)
    {
        cout<<"error"<<endl;
        exit(-1);
    }
    err = pthread_create(&tid2,NULL,clientRecv,arg);
    err = pthread_join(tid1,NULL);
    //fprintf(stdout,"err = %d\n",err);
    if(err != 0)
    {
        cout<<"error"<<endl;
        exit(-1);
    }
    err = pthread_join(tid2,NULL);
    if(err != 0)
    {
        cout<<"error"<<endl;
        exit(-1);
    }
    char tempbuf[20];
    sprintf(tempbuf,"ipcrm -q %d",msgid);         //执行shell命令写入到tempbuf当中
    system(tempbuf);

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值