結構與malloc
結構是C語言中重要的一環,malloc是一個重要的函數,它完成了動態內存分配,用malloc分配的內存塊要通過free釋放。通過結構可以將不同類型的數據組合成一個整體,關於結構指針,LINUX下編程經常會運用一個技巧,這個技巧用在申請緩沖區上,可以申請不同大小的緩沖區。
首先,來看一個概念消息隊列 ,一個或多個進程可向消息隊列寫入消息,而一個或多個進程可從消息隊列中讀取消息,Linux中的消息被描述成在內核地址空間的一個內部鏈表,每一個消息隊列由一個IPC的標識號唯一的標識,Linux 為系統中所有的消息隊列維護一個 msgque 鏈表,每個消息隊列都在系統范圍內對應唯一的鍵值,要獲得一個消息隊列的描述字,只需提供該消息隊列的鍵值即可。
傳遞給隊列的消息的數據類型是一個如下形式的結構,在Linux 的系統庫linux/msg.h 中,它是這樣定義的:
/* message buffer for msgsnd and msgrcv calls */
struct msgbuf {
long mtype; /* type of message */
char mtext[1]; /* message text */
};
其中,mtype成員代表消息類型,從消息隊列中讀取消息的一個重要依據就是消息的類型;mtext是消息內容。這個結構的精妙之處在於,mtext雖然在結構中被聲明為大小為1的字符,但實際消息內容的長度可以由程序員任意定制,定制的關鍵在malloc函數。下面是部分代碼段:msg=(struct msgbuf*)malloc(sizeof(struct msgbuf)+100);//100為消息的長度,msgbuf結構只有2個成員一個成員是mytpe,另一個成員是一個字節的mtext,在結構後分配更多的空間以存放消息字符串
完整代碼(演示了公共消息隊列的使用)為:
#define _GNU_SOURCE #include以上是發送消息,以下是接收消息#include #include #include #define QUE_ID 2 //使用公共消息隊列,讀寫進程可以不同時運行。 int main(void){ int queue_id; struct msgbuf *msg; int rc; //建立消息隊列 queue_id=msgget(QUE_ID,IPC_CREAT|0600);//QUE_ID為一個正整數,公共消息隊列的ID if (queue_id==-1){ perror(create queue error! ); exit(1); } printf(message %d queue created! ,queue_id); //創建發送消息結構 printf(message send.... ); msg=(struct msgbuf*)malloc(sizeof(struct msgbuf)+100);//100為消息的長度,msgbuf結構只有2個成員一個成員是mytpe,另一個成員是一個字節的mtext,在結構後分配更多的空間以存放消息字符串 msg->mtype=1;//消息類型,正整數 strcpy(msg->mtext,deepfuture.iteye.com); //發送消息 rc=msgsnd(queue_id,msg,100,0); //最後一個參數可以是是0與隨後這些值(或者就是0):IPC_NOWAIT,如果消息類型沒有則立即返回,函數調用失敗 //MSG_EXCEPT,當消息類型大於0時,讀與消息類型不同的第一條消息 //MSG_NOERROR,如果消息長度大於100字節則被截掉 if (rc==-1){ perror(msgsnd error ); exit(1); } free(msg);//發送完畢,釋放內存 printf(message sended! ); return 0; }
#define _GNU_SOURCE #include#include #include #include #define QUE_ID 2 //使用公共消息隊列,讀寫進程可以不同時運行。 int main(void){ int queue_id; struct msgbuf *msg; int rc; //取得消息隊列 queue_id=msgget(QUE_ID,0);//QUE_ID為一個正整數,公共消息隊列的ID, if (queue_id==-1){ perror(get queue error! ); exit(1); } printf(message recv.... ); msg=(struct msgbuf*)malloc(sizeof(struct msgbuf)+100); rc=msgrcv(queue_id,msg,101,0,0); if (rc==-1){ perror(recv error ); exit(1); } printf(recv:%s ,msg->mtext); return 0; }
效果
deepfuture@deepfuture-laptop:~/private/mytest$ ./testmessnd
message 0 queue created!
message send....
message sended!
deepfuture@deepfuture-laptop:~/private/mytest$ ./testmesrecv
message recv....
recv:deepfuture.iteye.com
deepfuture@deepfuture-laptop:~/private/mytest$