Linux利用共享記憶體實現多程序通訊非堵塞FIFO

2021-10-10 06:22:28 字數 4545 閱讀 4795

首先,共享記憶體屬於多程序的共享資源,必須保證讀寫是安全的,要確保乙個程序在寫的時候不能被讀,在乙個程序讀的時候,其他程序不能寫。所以可以選擇訊號量做同步,也可以選擇互斥量做同步。這裡我選擇了互斥量,因為互斥量時間開銷比訊號量小,而且後續可以結合條件變數做成堵塞的fifo (first in first out)。

實際使用中,往往是乙個程序寫,乙個程序讀。

#include #include #include #include #include #include #include #include struct share_buf_msg

;struct share_buffer

;typedef struct

shbuf_mnghead;

這裡我犯了個錯誤,就是把資料buffer也放在了結構體share_buf_msg 裡面,搞了半天,總是出現segment fault,兩個讀寫程序不能同時存在。。

初始化,申請兩塊共享記憶體,一塊是share_buf_msg,一塊是存資料用的buffer。一開始我是打算申請一大塊共享記憶體,前面少量位元組作為share_buf_msg用,剩下的作為buffer用(後來發現也是可以的)。就是因為剛開始我把buffer這個指標成員也放進了share_buf_msg,存放著共享記憶體的位址,這個指標佔的空間本身也在共享記憶體裡,導致第乙個程序執行之後,再執行第二個程序,初始化就出現segment fault了。因為第二個程序申請的buffer位址是邏輯位址,和第乙個程序的邏輯位址不一樣,buffer指標的值被第二個程序修改了,所以第乙個程序訪問的buffer就不對了,所以就segment fault了。

void *share_buffer_init(int size,int infoid,int bufid)

buffer_share->msg = (struct share_buf_msg *)shmat(mid,null,0);

if(buffer_share->msg == null)

else

}buffer_share->buffer = shmat(mid,null,0);

if(buffer_share->buffer == null)

if(buffer_share->msg->magic_key != bufid)

//sem_init(sem_key1); }

return (void *)buffer_share;

}

共享記憶體讀函式

//內部buffer操作函式,主要是注意處理buffer邊界問題,讀指標偏移

void sharebufferread(unsigned char *destbuf, int len, struct share_buf_msg *buffer_msg, unsigned char *shmbuffer)

else }

//讀函式

int share_buffer_read_api(struct share_buf_msg *buffer_msg, unsigned char *shmbuffer, unsigned char *data,int datasize) //,unsigned int registerid)

//取鎖

//sem_p();

pthread_mutex_lock(&buffer_msg->rw_mutex);

//取共享記憶體頭

sharebufferread((unsigned char *)&head, headsize, buffer_msg, shmbuffer);

len = head.packlen;

//讀取的資料如果小於一包的資料,不讀

if(datasize < len || buffer_msg->valid_size==0 || head.magic != shbuf_magic_num)

//更新讀指標

buffer_msg->readptr = (buffer_msg->readptr + headsize)% buffer_msg->buffer_size;

sharebufferread(data, len, buffer_msg, shmbuffer);

//更新讀指標

buffer_msg->readptr = (buffer_msg->readptr + len)% buffer_msg->buffer_size;

//更新可讀數量

buffer_msg->valid_size = buffer_msg->valid_size - headsize - len ;

printf("valid_size=%d\n",buffer_msg->valid_size);

//釋放鎖

//sem_v();

pthread_mutex_unlock(&buffer_msg->rw_mutex);

return len;

}

共享記憶體寫函式

int share_buffer_write_api(struct share_buf_msg *buffer_msg,unsigned char *shmbuffer,unsigned char *data,unsigned int datasize)

//用於校驗共享的資料頭

mnghead.magic = shbuf_magic_num;

//一包資料的長度

mnghead.packlen = datasize;

else

//更新寫指標

buffer_msg->writeptr = (buffer_msg->writeptr + mngheadsize)% buffer_msg->buffer_size;

} //拷貝資料

if(datasize!=0)

else

buffer_msg->writeptr= (buffer_msg->writeptr + datasize)% buffer_msg->buffer_size;

} buffer_msg->valid_size = buffer_msg->valid_size + datasize + mngheadsize;

//釋放鎖

//sem_v();

pthread_mutex_unlock(&buffer_msg->rw_mutex);

printf("write done!\n");

return 0;

}

測試寫 write.c

int main()

printf("mallac success!\n");

char data[50]="never say nothing to do, something worth to try!\n";

while(1)

free(sharebuffer);

return 0;

}

測試讀 read.c

int main()

printf("mallac success!\n");

char data[50]=;//"never say nothing to do,something worth to do!\n";

while(1)

return 0;

}

先執行讀程序,再執行寫程序,執行結果:

init!

mallac success!

magic 0, datasize =50 len =0

read ret=-1

read string:

magic 0, datasize =50 len =0

read ret=-1

read string:

magic 0, datasize =50 len =0

read ret=-1

read string:

mallac success!

magic 0, datasize =50 len =0

read ret=-1

read string:

getwrite lock!

write done!

write ret=0

getwrite lock!

write done!

write ret=0

valid_size=58

read ret=50

read string:never say nothing to do, something worth to try!

getwrite lock!

write done!

write ret=0

getwrite lock!

write done!

write ret=0

valid_size=116

read ret=50

read string:never say nothing to do, something worth to try!

至此,利用共享記憶體的非阻塞fifo已實現。

完整原始碼:

利用共享記憶體實現訊息佇列

日曆登入管理器 2009 02 28 22 02 44 分類 windows 標籤 舉報 字型大小大中 小訂閱 在windows中沒有方便操作message queue 訊息佇列 的api 在vxworks中有msgqcreate,msgqsend,msgqreceive等操作訊息佇列的 api 訊...

Linux共享記憶體實現方法

共享記憶體 1.共享記憶體概述 共享記憶體是允許兩個不相關的程序訪問同乙個邏輯記憶體的程序間通訊方法,是在兩個正 在執行的程序之間共享和傳遞資料的一種非常有效的方式。不同程序之間共享的記憶體通常安排為同一段物理記憶體。程序可以將同一段共享記憶體連線 到它們自己的位址空間中,所有程序都可以訪問共享記憶...

多程序通訊(IPC) 共享記憶體

1 共享記憶體介紹 共享記憶體可以說是最有用的程序間通訊方式,也是最快的ipc形式。兩個不同程序a b共享記憶體的意思是,同一塊物理記憶體被對映到程序a b各自的程序位址空間。程序a可以即時看到程序b對共享記憶體中資料的更新,反之亦然。由於多個程序共享同一塊記憶體區域,必然需要某種同步機制,互斥鎖和...