linux 訊息佇列執行個體講解

來源:互聯網
上載者:User

       在做linux多任務編程的時候,難免會碰到要使用IPC技術了,但是很多人都對這些技術只知其名,不知道如何使用。為了大家都能很好的學習Linux,本人不才,貼出了自己寫的 訊息佇列 編程,用的是多線程,不是多進程,原理一樣。以後有時間會後續把其他幾個技術一一詳解,並貼上代碼。好了,廢話不多說,進入下面的執行個體講解。

/*****************************************************

**標頭檔包含

****************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>  //ftok, msgget, msgrcv, msgsnd
#include <sys/ipc.h>   //ftok, msgget, msgrcv, msgsnd
#include <sys/msg.h> //ftok, msgget, msgrcv, msgsnd
#include <pthread.h> //多線程
#include <string.h> //memcpy
#include <unistd.h>
#define KEYFILE "/root/work/msgqueue"  //產生系統唯一的索引值所用,這個目錄或檔案一定要存在
#define PROJID 10  //產生系統唯一的索引值項目號。


struct msg{

 long type;  //訊息類型
 char buf[512]; //訊息內容
};

/*******************************************************

**建立系統唯一的索引值,為msgget所用,也可以不

**用調用此函數,用一個常數代替key,但是為避免

**建立的訊息佇列失敗,建議用此方法。

*******************************************************/

key_t CreateMsgKey()
{
 return ftok(KEYFILE,PROJID);//系統調用,返回一個系統唯一的索引值。

}

/********************************************************

**下面是建立一個線程,並設定為分離態,這個應該

**就不需要多說了吧。

*********************************************************/
pthread_t createthread(void* (*fun)(void *),void *arg)
{
 pthread_t threadId;
 pthread_attr_t attr;
 memset(&attr,0,sizeof(attr));
 pthread_attr_init(&attr);
 pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
 return  pthread_create(&threadId,&attr,fun,arg);

}

/*******************************************

**待會要建立的線程工作函數,此線程

**每隔2秒向訊息佇列裡發一條訊息。

********************************************/
void *DoSndMsg(void *arg)
{
 struct msg SndMsg;
 long iCount=1;
 SndMsg.type=100;//訊息類型為100
 int msgid=0;
 msgid=msgget(*(key_t *)arg,IPC_CREAT);//擷取訊息佇列的ID,arg是由進程傳進來的key,IPC_CREAT表示建立一個新的

                                                                           //訊息佇列,如果,如果key已經建立了訊息佇列,則返回已經建立的訊息佇列ID。

                                                                            //如果IPC_EXCL | IPC_CREAT一起用,如果key已經建立了訊息佇列,則返回錯誤。
 printf("msgid is:%d\n",msgid);  //列印下msgid
 while(iCount>0)
 {
  iCount+=1;;
  memcpy(SndMsg.buf,&iCount,sizeof(iCount));
  msgsnd(msgid,&SndMsg,sizeof(SndMsg),IPC_NOWAIT);//把sndmsg裡的訊息發送到msgid的訊息佇列裡,IPC_NOWAIT表示

                                                                                                      //不阻 塞。
  printf("iCount is:%ld\n",iCount);
  sleep(2);
 }
 return NULL;
}
int main()
{
 pthread_t sndThread;
 struct msg rcvMsg;
 int msgid;
 long rcvCount=0;
 key_t msgkey;
 msgkey=CreateMsgKey(); //建立key

 sndThread=createthread(DoSndMsg,&msgkey);//建立線程。
 msgid=msgget(msgkey,IPC_CREAT);//擷取訊息佇列ID
 printf("msgid is:%d\n",msgid);
 while(rcvCount==0)
 {
  msgrcv(msgid,&rcvMsg,sizeof(rcvMsg),0,IPC_NOWAIT);//接收msgid裡第一條訊息,0的位置是訊息類型,0,表示訊息佇列

                                                                                                   //第一條訊息,大於零的值則表示收取相應訊息類型的訊息。
  memcpy(&rcvCount,rcvMsg.buf,sizeof(rcvCount));
  printf("msgtype:%ld\n",rcvMsg.type);
  printf("rcvCount is:%ld\n",rcvCount);
  sleep(2);
  rcvCount=0;

 }

 return EXIT_SUCCESS;
}
          系統調用msgrcv中的參數type非常的重要,這個形參決定讀取訊息佇列中哪一條訊息,unix環境進階編程裡做了很好的總結,現在分享給大家。

          type==0, 表示讀取訊息佇列中的第一條訊息(任何類型的訊息都接收);

          type>0,   表示讀取訊息佇列中類型為type的第一條訊息(如果有多條同類型訊息,一次唯讀最前面的一條訊息);

          type<0,   表示讀取訊息佇列中類型為小於或者大於type絕對值的第一條訊息。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.