我们知道,消息队列是进程间通信的方法之一,
当然,消息队列也可以用于线程间通信。
进程间通信的时候,我们需要使用ftok()函数创建同一个key值,(当然,进程间通信,key值我们可以自定义同一个值,而不必非要调用ftok函数,这步可以省掉。)线程间通信时,我们就是采用直接自定义key值的方法,这样比较简便。
示例:
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
pthread_t pid_1,pid_2;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int msgid;
typedef struct{
long mtype;
int date;
}msg;
void *func2(void *arg)
{
int i = 1,j =1;
msg sendData;
pthread_detach(pthread_self());
while(1)
{
sleep(2);
sendData.mtype = i++;
sendData.date= j++;
if(( msgsnd(msgid,&sendData,sizeof(msg)-sizeof(sendData.mtype),0))<0)
{
perror("msgsnd:");
pthread_exit(NULL);
}else
{
pthread_mutex_lock(&mutex);
printf("send:mtype= %ld,data = %d\n",sendData.mtype,sendData.date);
pthread_mutex_unlock(&mutex);
}
}
}
void *func1(void *arg)
{
pthread_create(&pid_2,NULL,func2,NULL);
msg reData;
while(1)
{
if((msgrcv(msgid,&reData,sizeof(reData)-sizeof(reData.mtype),0,0))<0)
{
perror("msgrcv:");
pthread_exit(NULL);
}else{
pthread_mutex_lock(&mutex);
printf("recv:mtype= %ld,data = %d\n",reData.mtype,reData.date);
pthread_mutex_unlock(&mutex);
}
}
pthread_join(pid_2,NULL);
printf("func1--son exit \n");
}
int main(int argc, char *argv[])
{
if((msgid = msgget(3123,IPC_CREAT|0666))<0)
{
perror("msgget:");
return 0;
}
pthread_create(&pid_1,NULL,func1,NULL);
pthread_join(pid_1,NULL);
printf("main--son exit \n");
printf("father exit\n");
return 0;
}
运行结果:
总结:
1) 消息队列可以用于线程间通信;
2)在同一进程中的话,只需要msgget一次获得一个全局的消息id即可。
3)
msgrcv的使用,当没有消息过来时,msgrcv是阻塞在这里的,
此时的现象是,不会perror报错,也不会打印else中的内容,just阻塞在这里,
只有当msgsnd过来消息后,才会printf打印输出。
4)消息类型中的mtype必须是大于0的,测试改成0后,结果: