1. 程式人生 > >執行緒通訊程式---訊息佇列(Linux)

執行緒通訊程式---訊息佇列(Linux)

MSGQUEUE1.c


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

#define MSGKEY  1234
pthread_t tid[2]={0}; //定義一個數組,作為執行緒id

struct msgbuf 
{
    long mtype;     //訊息型別
    char
mtext[100]; //訊息內容 }; void *receive(void *arg) { struct msgbuf buf; //定義結構體用作訊息緩衝區 int ret; while(1) { memset(&buf,0,sizeof(buf)); //初始化 ret = msgrcv(*(int *)arg,&buf,sizeof(buf.mtext),2,0); if(-1 == ret) { perror("msgrcv"); exit
(1); } if(!strncmp(buf.mtext,"bye",3)) { pthread_cancel(tid[1]); //注意:要取消另一個程序哦 break; } printf("receive :%s\n",buf.mtext); } } void *send(void *arg) { struct msgbuf buf; int ret,oldtype; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);//收到訊號後立即執行取消動作(退出);oldtype用來存入取消動作的型別值。
while(1) { memset(&buf,0,sizeof(buf)); scanf("%s",buf.mtext); buf.mtype = 1; ret = msgsnd(*(int *)arg,&buf,sizeof(buf.mtext),0); if(-1 == ret) { perror("msgsnd"); exit(1); } if(!strncmp(buf.mtext,"bye",3)) { pthread_cancel(tid[0]); break; } } } int main() { int msgid,ret; msgid = msgget(MSGKEY,IPC_CREAT |IPC_EXCL); //建立訊息佇列,返回識別符號 if(-1 == msgid) { perror("msgid"); exit(1); } ret = pthread_create(&tid[0],NULL,receive,(void *)&msgid); //引數一:執行緒id;引數二:執行緒屬性(通常為空);引數三:執行緒要執行的函式;引數四:作為傳遞給引數三的引數 if(0 != ret) { perror("pthread_create1"); exit(1); } ret = pthread_create(&tid[1],NULL,send,(void *)&msgid); if(0 != ret) { perror("msgid"); exit(1); } pthread_join(tid[0],NULL);//阻塞呼叫執行緒,直到指定的執行緒終止 pthread_join(tid[1],NULL); msgctl(msgid,IPC_RMID,NULL);//移除訊息佇列 return 0; }

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

#define MSGKEY  1234
pthread_t tid[2]={0}; //定義一個數組,作為執行緒id

struct msgbuf 
{
    long mtype;     //訊息型別
    char mtext[100];  //訊息內容
};

void *receive(void *arg)
{
    struct msgbuf buf;  //定義結構體用作訊息緩衝區
    int ret;

    while(1)
    {
        memset(&buf,0,sizeof(buf));  //初始化

        ret = msgrcv(*(int *)arg,&buf,sizeof(buf.mtext),1,0);
        if(-1 == ret)
        {
            perror("msgrcv");
            exit(1);
        }
        if(!strncmp(buf.mtext,"bye",3))
        {
            pthread_cancel(tid[1]); //注意:要取消另一個程序哦
            break;
        }
        printf("receive another:%s\n",buf.mtext);
    }
}

void *send(void *arg)
{
    struct msgbuf buf;
    int ret,oldtype;

    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);//收到訊號後立即執行取消動作(退出);oldtype用來存入取消動作的型別值。
    while(1)
    {
        memset(&buf,0,sizeof(buf));
        scanf("%s",buf.mtext);
        buf.mtype = 2;

        ret = msgsnd(*(int *)arg,&buf,sizeof(buf.mtext),0);
        if(-1 == ret)
        {
            perror("msgsnd");
            exit(1);
        }
        if(!strncmp(buf.mtext,"bye",3))
        {
            pthread_cancel(tid[0]);
            break;
        }
    }
}

int main()
{
    int msgid,ret;

    msgid = msgget(MSGKEY,0); //建立訊息佇列,返回識別符號
    if(-1 == msgid)
    {
        perror("msgid");
        exit(1);
    }

    ret = pthread_create(&tid[0],NULL,receive,(void *)&msgid); //引數一:執行緒id;引數二:執行緒屬性(通常為空);引數三:執行緒要執行的函式;引數四:作為傳遞給引數三的引數
    if(0 != ret)
    {
        perror("pthread_create1");
        exit(1);
    }

    ret = pthread_create(&tid[1],NULL,send,(void *)&msgid);
    if(0 != ret)
    {
        perror("msgid");
        exit(1);
    }

    pthread_join(tid[0],NULL);//阻塞呼叫執行緒,直到指定的執行緒終止
    pthread_join(tid[1],NULL);

    return 0;
}




執行結果:
    receive :hi         hi
    receive :i          i am your father
    receive :am         receive another:fuck
    receive :your       receive another:what
    receive :father     receive another:you
    fuck                receive another:say
    what you say
    bye