1. 程式人生 > >互相獨立程序間共享記憶體互斥訪問的解決辦法

互相獨立程序間共享記憶體互斥訪問的解決辦法

前提:兩個程序互相獨立,訪問同一片共享記憶體

存在問題:

1、如何避免兩個程序同時訪問共享記憶體(一旦兩個程序同時訪問一個臨界區,後果是程式崩潰)

2、如果使用互斥鎖,如何讓兩個程序拿到同一個互斥鎖

解決辦法:

針對問題1,可以使用訊號,訊號量,互斥鎖來進行同步,但是訊號和訊號量需要兩個程序都實現一套自己的邏輯(訪問臨界區前,先檢查衝突標誌,如果沒有衝突則訪問,並向其它的所有程序依次傳送訊號,告訴它們我要開始訪問了;如果有衝突則阻塞等待。同時程序收到訊號後要設定衝突標誌,標識現在有其它程序在訪問),比較麻煩,兩個程序的話還比較簡單,多個程序的話在訪問共享記憶體前要通知所有的其它程序。所以最終決定使用互斥鎖來完成同步訪問。那麼就出現了第二個問題,如何讓兩個程序拿到同一個互斥鎖。

針對問題2,可以使用下面的解決方案:互斥量儲存在共享記憶體中,在初始化該鎖的時候,設定為程序間共享,這樣兩個程序連線到共享記憶體後,都可以獲得這個互斥鎖,因為已經設定了程序間共享,所以對鎖的訪問的衝突問題,系統已經解決了。

程式碼如下,以經過測試:

//processA.c檔案
#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <errno.h>
#include <pthread.h>

#define BUF_SIZE 4096

int main()
{
    void *shm_addr = NULL;
    char buffer[BUF_SIZE];
	pthread_mutex_t * sharedLock;
	pthread_mutexattr_t ma;

    int shmid;
    // 使用約定的鍵值建立共享記憶體
    shmid = shmget((key_t) 1234,  BUF_SIZE, 0666 | IPC_CREAT);
    printf("shmid : %u\n", shmid);
    if (shmid < 0)
    {
        perror("shmget error!");
        exit(1);
    }

    // 將共享記憶體附加到本程序
    shm_addr = shmat(shmid, NULL, 0);
    if (shm_addr == (void *) -1)
    {
        perror("shmat error!");
        exit(1);
    }

	sharedLock = (pthread_mutex_t *)shm_addr;

	pthread_mutexattr_init(&ma);
	pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED);
	pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST);
	pthread_mutex_init(sharedLock,&ma);

    // 寫入資料
    while(1){
    	pthread_mutex_lock(sharedLock);
    	bzero(buffer, BUF_SIZE);
    	sprintf(buffer, "Hello, My PID is %u\n", (unsigned int) getpid());
    	printf("send data: %s\n", buffer);
    	memcpy(((pthread_mutex_t *)shm_addr)+1, buffer, strlen(buffer));
		pthread_mutex_unlock(sharedLock);
    }

    sleep(5);

    // 分離
    if (shmdt(shm_addr) == -1)
    {
        printf("shmdt error!\n");
        exit(1);
    }
}

//processB.c檔案
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>

#define BUF_SIZE 4096

int main()
{
    void *shm_addr = NULL;
	pthread_mutex_t * sharedLock;
	char tmp[BUF_SIZE];

    int shmid;
    // 使用約定的鍵值開啟共享記憶體
    shmid = shmget((key_t) 1234, BUF_SIZE, IPC_CREAT);
    printf("shmid : %u\n", shmid);
    if (shmid == -1)
    {
        perror("shmget error!");
        exit(1);
    }

    // 將共享記憶體附加到本程序
    shm_addr = shmat(shmid, NULL, 0);
    if (shm_addr == (void *) -1)
    {
        perror("shmat error!");
        exit(1);
    }

	sharedLock = (pthread_mutex_t *)shm_addr;

    // 讀取資料
    while(1){
		pthread_mutex_lock(sharedLock);
    	bzero(tmp, BUF_SIZE);
    	memcpy(tmp, ((pthread_mutex_t *)shm_addr)+1, 50);
    	printf("read from shared memory: %s\n", tmp);
		pthread_mutex_unlock(sharedLock);
    }

    sleep(5);

    // 分離
    if (shmdt(shm_addr) == -1)
    {
        printf("shmdt error!\n");
        exit(1);
    }

    // 刪除共享記憶體
    if (shmctl(shmid, IPC_RMID, 0) == -1)
    {
        printf("shmctl error!\n");
        exit(1);
    }
}

經過測試,兩個程序確實實現了互斥訪問,且沒有出現程式崩潰。

相關推薦

互相獨立程序共享記憶體互斥訪問解決辦法

前提:兩個程序互相獨立,訪問同一片共享記憶體存在問題:1、如何避免兩個程序同時訪問共享記憶體(一旦兩個程序同時訪問一個臨界區,後果是程式崩潰)2、如果使用互斥鎖,如何讓兩個程序拿到同一個互斥鎖解決辦法:針對問題1,可以使用訊號,訊號量,互斥鎖來進行同步,但是訊號和訊號量需要兩

檔案記憶體對映mmap解決大檔案快速讀寫問題和程序共享記憶體

mmap函式主要用途有三個: 1、將一個普通檔案對映到記憶體中,通常在需要對檔案進行頻繁讀寫時使用,這樣用記憶體讀寫取代I/O讀寫,以獲得較高的效能; 2、將特殊檔案進行匿名記憶體對映,可以為關聯程序提供共享記憶體空間; 3、為無關聯的程序提供共享記憶體空間,一般也是將一個普通檔案對映到

Qt程序共享記憶體例子

一、現實需求: 專案中有一個FPGA需要實時高速大資料量採集投影資料,需要將驅動單獨編寫成一個程序,並將檔案地址及時共享給另外一個應用程式程序。 以前測試過將兩個程式放在一個程序裡,多執行緒執行。但是有應用程式處理過慢,迴圈佇列會溢位的問題。而且多次編譯程式,多次開啟

Boost.Interprocess使用手冊翻譯之四:在程序共享記憶體 (Sharing memory between processes)

共享記憶體 共享記憶體是最快速的程序間通訊機制。作業系統在幾個程序的地址空間上對映一段記憶體,然後這幾個程序可以在不需要呼叫作業系統函式的情況下在那段記憶體上進行讀/寫操作。但是,在程序讀寫共享記憶體時,我們需要一些同步機制。 考慮一下服務端程序使用網路機制在同一臺

Linux下的多程序共享資源的互斥訪問

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

程序通訊 記憶體共享訊號量例項理解

申請記憶體: int shmget(key_t key, size_t size, int shmflg); 其中key為鑰匙,兩程序通過同一個鑰匙找到核心中的共享記憶體,可通過 key_t ftok(const char *pathname, int proj_id)

linux程序通訊———記憶體共享

共享記憶體(shared memory):是linux下的多程序之間的通訊方法,這種方法通常用於一個程式的多程序間通訊,實際上多個程式間也可以通過共享記憶體來傳遞資訊。共享記憶體指在多處理器的計算機系統中,可以被不同中央處理器(CPU)訪問的大容量記憶體。由於多

CreateFileMapping在N個程序共享一個HWND型別記憶體

Windows高深啊,做點東西要查來查去,把人腦創造性轉成機器服務 C/C++ code ? 1 2 3 4 5 6 7 8 9 10 11 12 13

Python 程序共享變數(多程序通訊安全)

import multiprocessing import time def worker(d, key, value): d[key] = value if __name__ == '__main__': mgr = multiprocessing.Manager()

作業系統(程序間共享儲存區的通訊):建立一個共享儲存區,大小4個位元組(int大小)。建立一個子程序,然後子父程序獨自執行。父程序寫入一個數字到共享儲存區,子程序共享儲存區把該數字讀出

題目:建立一個共享儲存區,大小4個位元組(int大小)。建立一個子程序,然後子父程序獨自執行。父程序寫入一個數字到共享儲存區,子程序在共享儲存區把該數字讀出。 程式碼量很少,純屬應付作業 筆者在telnet上寫這些程式碼,由於知識技術及英語太菜,不知道怎樣在telnet上覆製出來這些程式碼,

【Linux 程序】fork父子程序共享資料分析

之前我們通過fork()函式,得知了父子程序之間的存在著程式碼的拷貝,且父子程序都相互獨立執行,那麼父子程序是否共享同一段資料,即是否存在著資料共享。接下來我們就來分析分析父子程序是否存在著資料共享。 我們都知道,在linux下,記憶體儲存的位置是 全域性變數,棧區,堆區,以及檔案 。字元常量

程序程式設計——共享記憶體

程序間通訊有四種方式:訊號量、管道、訊息佇列、共享記憶體 我們之前已著重介紹過訊號量、管道。 現著重介紹一下共享記憶體。 共享記憶體        共享記憶體是最高效的IPC機制,因為它不涉及程序之間任何的資料傳輸。這種高效率帶來的問題是,我們

Linux程序通訊-共享記憶體

共享記憶體是被多個程序共享的一部分實體記憶體。共享記憶體是程序間共享資料一種最快的方法,一個程序向共享記憶體區域寫入了資料,共享這個記憶體區域的所有程序就可以立刻看到其中的內容。 建立共享記憶體分為兩個步驟: 1、建立共享記憶體,使用shmget函式 2、對映共享記憶體,將這段建立的共

Linux中的程序通訊-------共享記憶體

一、什麼是共享記憶體 顧名思義,共享記憶體就是允許兩個不相關的程序訪問同一個邏輯記憶體。共享記憶體是在兩個正在執行的程序之間共享和傳遞資料的一種非常有效的方式。不同程序之間共享的記憶體通常安排為同一段實體記憶體。程序可以將同一段共享記憶體連線到它們自己的地址空間

Windows程序共享核心物件幾種方式

核心物件的控制代碼是程序相關的,這樣更可靠,更安全;Windows提供下列N種機制來允許程序共享核心物件。 使用物件控制代碼繼承 只有程序間存在父子關係才能使用物件控制代碼繼承;系統會遍歷父程序的控制代碼表將所有有效的控制代碼完整的複製到子程序的控制代碼表中(這

python爬蟲入門八:多程序/多執行緒 python佇列Queue Python多執行緒(2)——執行緒同步機制 python學習筆記——多程序共享記憶體Value & Array python 之 多程序 Python多程序 Python 使用multiprocessing 特別耗記

什麼是多執行緒/多程序 引用蟲師的解釋: 計算機程式只不過是磁碟中可執行的,二進位制(或其它型別)的資料。它們只有在被讀取到記憶體中,被作業系統呼叫的時候才開始它們的生命期。 程序(有時被稱為重量級程序)是程式的一次執行。每個程序都有自己的地址空間,記憶體,資料棧以及其它記錄其執行軌跡的輔助資料

一起talk C栗子吧(第一百回:C語言例項--使用訊號量進行程序同步與互斥一)

各位看官們,大家好,上一回中咱們說的是程序間同步與互斥的例子,這一回咱們說的例子是:使用訊號量進行程序間同步與互斥。閒話休提,言歸正轉。讓我們一起talk C栗子吧! 看官們,訊號量是由著名電腦科學家迪傑斯特拉(Dijkstra)提出的一種概念,專門用來

筆記:程序通訊——同步(互斥鎖、讀寫鎖、條件變數、訊號量)以及Linux中的RCU

1.互斥鎖 多個執行緒的IPC,需要同步,同步有隱式的和顯示的: 比如unix提供的管道和FIFO,由核心負責同步,比如read發生在write之前,那麼read就會被核心阻塞,這中同步是由核心負責的,使用者不會感知。 但如果使用共享區作為生產者和消費者之間的IPC,那麼程

程序退出共享記憶體不一定釋放

如下程式,在backtrace (array, 10)中,申請5次記憶體,程序退出並沒有立即釋放。Valgrind檢測結果如下: [[email protected] memory]# valgrind --tool=memcheck ./sample ==6452== Memcheck, a

多個程序共享動態連結庫的原理

同樣這個問題是我在面試總監的時候,總監問我的一個問題,這些天一直 忙活,都沒有好好看書了,今天總結一下這個問題?為什麼一個程序用完一個動態連結庫以後另一個程序還可以繼續使用呢?當時回答的很是籠統,只說對了答案的一半,現在就在這裡好好總結一下吧! 前面我們已經說過程序間的通訊有好幾種方式,其實現在我們講的這種動