執行緒通訊程式---訊息佇列(Linux)
阿新 • • 發佈:2019-02-08
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