Linux多线程同步之消息队列 |
发布时间: 2012/8/10 10:26:20 |
消息队列是消息的链表,存放在内核中并有消息队列标示符标示。
msgget用于创建一个新队列或打开一个现存的队列。msgsnd将新消息加入到消息队列中;每个消息包括一个long型的type;和消息缓存;msgrcv用于从队列中取出消息;取消息很智能,不一定先进先出 ①msgget,创建一个新队列或打开一个现有队列 #include int msgget ( key_t key, int flag ); //成功返回消息队列ID;错误返回-1 ②msgsnd: 发送消息 #include int msgsnd( int msgid, const void* ptr, size_t nbytes, int flag ) //成功返回0,错误返回-1 a: flag可以指定为IPC_NOWAIT; 若消息队列已满,则msgsnd立即出错返回EABAIN; 若没指定IPC_NOWAIT; msgsnd会阻塞,直到消息队列有空间为止 ③msgrcv: 读取消息: ssize_t msgrcv( int msgid, void* ptr, size_t nbytes, long type, int flag ); a. type == 0; 返回消息队列中第一个消息,先进先出 b. type > 0 返回消息队列中类型为tpye的第一个消息 c. type < 0 返回消息队列中类型 <= |type| 的数据;若这种消息有若干个,则取类型值最小的消息 消息队列创建步骤: #define MSG_FILE "." struct msgtype { long mtype; char buffer[BUFFER+1]; }; if((key=ftok(MSG_FILE,'a'))==-1) { fprintf(stderr,"Creat Key Error:%sn", strerror(errno)); exit(1); } if((msgid=msgget(key, IPC_CREAT | 0666/*PERM*/))==-1) { fprintf(stderr,"Creat Message Error:%sn", strerror(errno)); exit(1); } msg.mtype = 1; strncpy(msg.buffer, argv[1], BUFFER); msgsnd(msgid, &msg, sizeof(struct msgtype), 0); msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0); 示例代码: #include #include #include #include #include #include #include #include #include #define MSG_FILE "." #define BUFFER 255 #define PERM S_IRUSR|S_IWUSR #define IPCKEY 0x111 struct msgtype { long mtype; char buffer[BUFFER+1]; }; void* thr_test( void* arg ){ struct msgtype msg; int msgid; msgid = *((int*)arg); printf("msqid = %d IPC_NOWAIT = %dn", msgid, IPC_NOWAIT); time_t tt = time(0)+8; //while( time(0) <= tt ) //{ msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0); fprintf(stderr,"Server Receive:%sn", msg.buffer); msg.mtype = 2; msgsnd(msgid, &msg, sizeof(struct msgtype), 0); //} pthread_exit( (void*)2 ); } int main(int argc, char **argv) { struct msgtype msg; key_t key; int msgid; pthread_t tid; if(argc != 2) { fprintf(stderr,"Usage:%s stringn", argv[0]); exit(1); } /* char path[256]; sprintf( path, "%s/", (char*)getenv("HOME") ); printf( "path is %sn", path ); msgid=ftok( path, IPCKEY ); */ if((key=ftok(MSG_FILE,'a'))==-1) { fprintf(stderr,"Creat Key Error:%sn", strerror(errno)); exit(1); } if((msgid=msgget(key, IPC_CREAT | 0666/*PERM*/))==-1) { fprintf(stderr,"Creat Message Error:%sn", strerror(errno)); exit(1); } pthread_create( &tid, NULL, thr_test, &msgid ); fprintf(stderr,"msid is :%dn", msgid); msg.mtype = 1; strncpy(msg.buffer, argv[1], BUFFER); msgsnd(msgid, &msg, sizeof(struct msgtype), 0); exit(0); } 本文出自:亿恩科技【www.enkj.com】 |