㈠ linux編程的利用消息隊列在兩個進程間通信,怎麼寫代碼,求思路,需要建立幾個消息隊列呢
首先建議你先參考 《advanced programming in the unix environment》 一書中的第15章(Interprocess communication 進程間通信)中的第7節(message queues 消息隊列)了解消息隊列的相關介面函數,比如如何創建獲取消息隊列,如何收發消息。然後就很簡單了
如果你打算兩個進程依次收消息,發消息,就像打乒乓球一樣,那麼只要一個queue,A 發消息, B 收消息並處理,然後 B 發消息, A 收並處理………… 按此次序進行下去。
更靈活的方法是兩個消息隊列 (a, b), A 進程從 隊列a收消息,向 b 發消息。 B進程從b收消息,想a發消息。
㈡ 簡述Linux進程間通信的幾種方式
進程間通訊進程間通信就是不同進程之間傳播或交換信息,進程的用戶空間是互相獨立的,進程之間可以利用系統空間交換信息。
管道(pipe)管道是一種半雙工的通信方式,數據只能單向流動。如果要進行雙工通信,需要建立兩個管道。
管道只能在具有親緣關系的進程間使用,例如父子進程或兄弟進程。
有名管道(named
pipe)
有名管道也是雙半工的通信方式,但它允許無親緣關系的進程間使用。
信號量(semophore)
信號量常用來作為一種鎖機制來使用,它是一個記數器,用來控制多進程對共享資源的訪問,防止多個進程同時訪問一個共享資源。信號量主要用作為進程間或同一進程間不同線程之間的同步手段。
信號(sinal)
信號是一種比較復雜的通信方式,用於通知接收進程某些事件已經發生,要注意信號處理中調用的函數是否為信號安全。
消息隊列(message
queue)
消息隊列是由消息的鏈表組成,存放在內核中並由消息隊列標識符標識。
共享內存(shared
memory)
共享內存就是映射一段被其他進程所訪問的內存,這段共享內存由一個進程創建,可由多個進程訪問。共享內存是最快的IPC方式,它是針對其他進程間通信方式的低運行效率而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。
套接字(socket)
套接字也是進程間通信的一種方式,與其他方式不同的是,它可以用在不同主機間的進程通信(也是它的主要用途)。
幾種方式的缺點
管道:
速度慢,容量有限,只能用於親緣關系進程間通信。
有名管道:
同管道,不過允許無親緣關系進程間通信。
消息隊列:
容量受系統限制,隊列中會遺留數據,讀時要考慮到這些未讀完的數據。
信號量:
主要用於同步,無法傳遞復雜的數據信息。
㈢ 請教一個關於linux進程通信消息隊列mq
在Linux中使用消息隊列
Linux提供了一系列消息隊列的函數介面來讓我們方便地使用它來實現進程間的通信。它的用法與其他兩個System V PIC機制,即信號量和共享內存相似。
1、msgget函數
該函數用來創建和訪問一個消息隊列。它的原型為:
int msgget(key_t, key, int msgflg);
與其他的IPC機制一樣,程序必須提供一個鍵來命名某個特定的消息隊列。msgflg是一個許可權標志,表示消息隊列的訪問許可權,它與文件的訪問許可權一樣。msgflg可以與IPC_CREAT做或操作,表示當key所命名的消息隊列不存在時創建一個消息隊列,如果key所命名的消息隊列存在時,IPC_CREAT標志會被忽略,而只返回一個標識符。
它返回一個以key命名的消息隊列的標識符(非零整數),失敗時返回-1.
msgsnd函數
該函數用來把消息添加到消息隊列中。它的原型為:
int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
msgid是由msgget函數返回的消息隊列標識符。
msg_ptr是一個指向准備發送消息的指針,但是消息的數據結構卻有一定的要求,指針msg_ptr所指向的消息結構一定要是以一個長整型成員變數開始的結構體,接收函數將用這個成員來確定消息的類型。所以消息結構要定義成這樣:
struct my_message{
long int message_type;
/* The data you wish to transfer*/
};
msg_sz是msg_ptr指向的消息的長度,注意是消息的長度,而不是整個結構體的長度,也就是說msg_sz是不包括長整型消息類型成員變數的長度。
msgflg用於控制當前消息隊列滿或隊列消息到達系統范圍的限制時將要發生的事情。
如果調用成功,消息數據的一分副本將被放到消息隊列中,並返回0,失敗時返回-1.
㈣ Linux下編程消息隊列怎麼封裝較好,怎麼保證2個進程能用同一個消息隊列
消息隊列就是用來進程間通信的, 每個進程只要知道消息隊列的queueID即可
#ifndef CMSGOP_H
#define CMSGOP_H
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
class CMsgOp
{
public:
CMsgOp();
virtual ~CMsgOp();
typedef struct _customMessageFormat{
int processID;
int cmd;
int commandArg;
}CCustomMessageFormat;
int init();
int send(const CCustomMessageFormat &message);
int receive(CCustomMessageFormat &message);
private:
int msgQueueID;
struct msgbuf sendBuf;
struct msgbuf recvBuf;
};
#endif // CMSGOP_H
#include "cmsgop.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
CMsgOp::CMsgOp()
{
}
CMsgOp::~CMsgOp()
{
msgctl(msgQueueID, IPC_RMID, NULL);
}
int CMsgOp::init()
{
key_t key = ftok("/home/maemo/tmp2", 1);
if(-1 == key)
{
perror("ftok failed!");
return -1;
}
int ret = msgget(key, IPC_CREAT);
if(-1 == ret)
{
perror("create message queue failed!");
return -1;
}
msgQueueID = ret;
return 0;
}
int CMsgOp::send(const CCustomMessageFormat &message)
{
memcpy(sendBuf.mtext, &message, sizeof(CCustomMessageFormat));
sendBuf.mtype = 1;
int ret = msgsnd(msgQueueID, &sendBuf, sizeof(CCustomMessageFormat), 0);
if(-1 == ret)
{
perror("message send failed!");
return ret;
}
}
int CMsgOp::receive(CCustomMessageFormat &message)
{
int ret = msgrcv(msgQueueID, &recvBuf, sizeof(CCustomMessageFormat), 0, IPC_NOWAIT);
if(-1 == ret)
{
perror("receive message failed!");
return -1;
}
memcpy(&message, recvBuf.mtext, sizeof(CCustomMessageFormat));
return ret;
}
㈤ 請教一個關於linux消息隊列的問題
一般使用步驟:
1. 用ftok產生一個key。
2. 調用msgget(使用key作為參數)產生一個隊列
3. 進程可以用msgsnd發送消息到這個隊列,相應的別的進程用msgrcv讀取。
這里需要注意msgsnd可能會失敗的兩個情況:
a) 可能被中斷打斷(包括msgsnd和msgrcv). 尤其是大流量應用中更容易出現. 比較安全的用法是判斷操作是否被中斷打斷,如果被打斷, 則需要繼續嘗試。
b) 消息隊列滿。產生這個錯誤,則需要考慮提高系統消息隊列規格,或者查看消息接收處是否有問題
4. msgctl函數可以用來刪除消息隊列
消息隊列產生之後,除非明確的刪除(可以用),產生的隊列會一直保留在系統中。linux下消息隊列的個數是有限的,注意不要泄露。如果 使用已經達到上限,msgget調用會失敗,產生的錯誤碼對應的提示信息為no space left on device.
注意點:
1.消息的類型 mtype 不需為非0值。如果使用0,則msgsnd會失敗,並得到」Invalid argument「錯誤。
2.msgflg為0表示阻塞等待,如果msgflg為IPC_NOWAIT表示非阻塞。
3.最好使用root許可權執行消息隊列,否則msgrcv 提示 "Permission denied"。
㈥ linux進程間通信(消息隊列)
在與此進程P1通信的進程P2中,同樣的以ftok創建KEY, msgget在該KEY上創建消息隊列,
只需要保證,ftok的參數中,第一個參數,即文件,是同一個文件即可。當P2中的文件與P1不同時,msgget函數將會返回錯誤。
可以說,消息隊列也是通過文件實現的,就像創建一個socket,要使用它時,也已經為其綁定了一個文件fd。
有一個例子不錯,你可以看看。實驗時,需要把ftok的第一個參數,即文件,設置為一個你當前目錄存在的文件。你可以touch一個臨時文件來實驗。
http://blog.csdn.net/lcrystal623/archive/2007/03/16/1531183.aspx
同時,謝謝link的博主。
㈦ linux 消息隊列編程
兩個進程用相同的key,就能共享了。 之後就能通訊了。例如下面用1234做key
//接收方
msgid=msgget((key_t)1234,0666|IPC_CREAT);
if(msgrcv(msgid,(void*)&data,BUFSIZ,msgtype,0)==-1)
{
fprintf(stderr,"msgrcvfailedwitherrno:%d ",errno);
exit(EXIT_FAILURE);
}
//發送方
msgid=msgget((key_t)1234,0666|IPC_CREAT);
if(msgsnd(msgid,(void*)&data,MAX_TEXT,0)==-1)
{
fprintf(stderr,"msgsndfailed ");
exit(EXIT_FAILURE);
}
㈧ Linux進程間通信的方式有哪些
第一種:管道通信
兩個進程利用管道進行通信時,發送信息的進程稱為寫進程;接收信息的進程稱為讀進程。管道通信方式的中間介質就是文件,通常稱這種文件為管道文件,它就像管道一樣將一個寫進程和一個讀進程連接在一起,實現兩個進程之間的通信。寫進程通過寫入端往管道文件中寫入信息;讀進程通過讀出端從管道文件中讀取信息。兩個進程協調不斷地進行寫和讀,便會構成雙方通過管道傳遞信息的流水線。
第二種:消息緩沖通信
多個獨立的進程之間可以通過消息緩沖機制來相互通信。這種通信的實現是以消息緩沖區為中間介質,通信雙方的發送和接收操作均以消息為單位。在存儲器中,消息緩沖區被組織成隊列,通常稱之為消息隊列。消息隊列一旦創建後即可由多進程共享,發送消息的進程可以在任意時刻發送任意個消息到指定的消息隊列上,並檢查是否有接收進程在等待它所發送的消息。若有則喚醒它,而接收消息的進程可以在需要消息的時候到指定的消息隊列上獲取消息,如果消息還沒有到來,則轉入睡眠等待狀態。
第三種:共享內存通信
針對消息緩沖需要佔用CPU進行消息復制的缺點,OS提供了一種進程間直接進行數據交換的通信方式。共享內存,顧名思義這種通信方式允許多個進程在外部通信協議或同步,互斥機制的支持下使用同一個內存段進行通信,它是一種最有效的數據通信方式,其特點是沒有中間環節,直接將共享的內存頁面通過附接映射到相互通信的進程各自的虛擬地址空間中,從而使多個進程可以直接訪問同一個物理內存頁面。
㈨ linux系統編程中的消息隊列該怎麼使用呀
消息隊列用於進程間通信,每個進程可以,只要該消息queueID隊列
的#ifndef CMSGOP_H
#定義CMSGOP_H
#包括類型。 H>
#包括ipc.h>
#包括msg.h>中
類CMsgOp
{
公眾:
CMsgOp ();
虛擬CMsgOp();
typedef結構_customMessageFormat {
整數PROCESSID;
整數CMD;
整數commandArg;
} CCustomMessageFormat; BR p>詮釋的init();
整數發送(常量CCustomMessageFormat&消息);
整數接收(CCustomMessageFormat&消息);
私人:
整數msgQueueID;
結構msgbuf sendBuf;
結構msgbuf recvBuf;
};
#ENDIF / / CMSGOP_H
的#include「 cmsgop.h「
#包括中
#包括中
#包括中
CMsgOp :: CMsgOp()
> {
}
CMsgOp ::CMsgOp()
{
了msgctl(msgQueueID,IPC_RMID,NULL);
}
BR />整型CMsgOp :: init()中
的key_t的key = ftok的(「/ home/maemo/tmp2」,1);
如果(-1 ==鍵) {
PERROR(「ftok的失敗!」);
返回-1;
}
整數RET = msgget(鍵,IPC_CREAT);
>如果(-1 == RET)
{
PERROR(「創建消息隊列失敗!」);
返回-1;
}
msgQueueID = RET;
返回0;
}
整數CMsgOp ::發送(常量CCustomMessageFormat&消息)
{的memcpy(sendBuf.mtext,及訊息,大小(CCustomMessageFormat));
sendBuf.mtype = 1;
整數RET =的msgsnd(msgQueueID,&sendBuf,大小(CCustomMessageFormat),0);
如果(-1 = = RET)
{
PERROR(「消息發送失敗!」);
返回RET;
}
}
整數CMsgOp: :接收(CCustomMessageFormat&消息)
{
整數RET =的msgrcv(msgQueueID,與recvBuf,大小(CCustomMessageFormat),0,IPC_NOWAIT);
如果( - 1 == RET) {
PERROR(「接收消息失敗!」);
返回-1;
}
的memcpy(&消息,recvBuf.mtext,大小(CCustomMessageFormat ));
返回RET;
}