2014-12-06 108 views
1

我有程序A和程序B.程序A使用shmget創建一個存儲到共享內存中的隊列,然後是shmat。進程B啓動,然後使用相同的shmid獲得進程A在沒有問題的情況下生成的隊列。進程A(A和B都明顯在同一時間運行),然後運行修改隊列中某個元素的方法。當程序A這樣做時,指向該內存塊的指針給我一個分段錯誤。可能是因爲程序B現在有指向它的指針我想。 我的問題是我該如何解決這個問題,以便程序A可以編輯和讀取隊列以及程序B.我知道我需要某種鎖,但不知道什麼樣的鎖最好或者如何正確執行這個。如果你可以提供一些示例代碼來解釋你的解釋,那將會有很大的幫助。我正在用C編寫所有這些,並且進程A有兩個鍵,一個用於隊列,另一個用於存儲程序B共享內存中分配的每個段的所有shmids,供程序B用來檢索那個信息。如何在兩個進程之間協調共享內存

+2

你可能不希望爲您解決問題這種方式。如果你真的想得到很好的幫助,你應該說明你的根本問題。 – 2014-12-06 21:40:06

+0

您將使用命名的(系統範圍的)信號量/互斥量。這裏有一個相關的討論:http://stackoverflow.com/questions/8359322/how-to-share-semaphores-between-processes-using-shared-memory – Archie 2014-12-06 22:29:47

回答

1

我同意評論說可能有更好的方法來解決潛在的問題,例如,與管道。但是,由於我的測試代碼完全符合您的描述,因此我會與您分享。請注意,運行此代碼時,應始終在啓動客戶端之前啓動服務器。

除了共享內存之外,代碼還創建了一對信號燈。客戶端使用REQUEST_SEM向服務器發出數據可用的信號。服務器使用RESPONSE_SEM表示它已完成客戶端的請求。

如果您決定更改共享內存的大小,則需要使用ipcrm命令刪除先前分配的共享內存。另一個有用的命令是ipcs,它列出了您創建的IPC對象。

最後一個注意事項。使用硬編碼key是不好的。請參閱ftok的文檔以獲取生成key的更好方法。

Server.c

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/sem.h> 
#include <sys/shm.h> 
#include <errno.h> 

#define REQUEST_SEM 0 
#define RESPONSE_SEM 1 

#define SEM_RA (SEM_R | SEM_A) 
#define SEM_FLAGS (SEM_RA | (SEM_RA >> 3) | (SEM_RA >> 6)) 
#define MEM_RW (SHM_R | SHM_W) 
#define MEM_FLAGS (MEM_RW | (MEM_RW >> 3) | (MEM_RW >> 6)) 

static void error(const char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 

void waitForIt(int semid, int semnum) 
{ 
    struct sembuf operations = { semnum, -1, 0 }; 

    if (semop(semid, &operations, 1) < 0) 
     error(__func__); 
} 

void signalIt(int semid, int semnum) 
{ 
    struct sembuf operations = { semnum, 1, 0 }; 

    if (semop(semid, &operations, 1) < 0) 
     error(__func__); 
} 

int main(int argc, char *argv[]) 
{ 
    int i, semID, memID, good, bad; 
    char *memAddress; 

    if ((semID = semget(0x1001, 2, IPC_CREAT | SEM_FLAGS)) < 0) 
     error("Unable to create semaphores"); 
    if (semctl(semID, REQUEST_SEM, SETVAL, 0) < 0) 
     error("Unable to initialize request semaphore"); 
    if (semctl(semID, RESPONSE_SEM, SETVAL, 0) < 0) 
     error("Unable to initialize response semaphore"); 

    if ((memID = shmget(0x1001, 1024, IPC_CREAT | MEM_FLAGS)) < 0) 
     error("Unable to create shared memory"); 
    memAddress = shmat(memID, NULL, 0);  
    if (memAddress == NULL || memAddress == ((void *) -1)) 
     error("Unable to attach shared memory"); 

    good = 0; 
    bad = 0; 
    for (i = 0; i < 100; i++) 
    { 
     waitForIt(semID, REQUEST_SEM); 
     if (memAddress[0] == i) 
      good++; 
     else 
      bad++; 

     memAddress[0] = 0x55; 
     signalIt(semID, RESPONSE_SEM); 
    } 

    printf("good=%d bad=%d\n", good, bad); 

    if (shmdt(memAddress) < 0) 
     error("Unable to detach shared memory"); 
} 

Client.c

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/sem.h> 
#include <sys/shm.h> 
#include <errno.h> 

#define REQUEST_SEM 0 
#define RESPONSE_SEM 1 

static void error(const char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 

void waitForIt(int semid, int semnum) 
{ 
    struct sembuf operations = { semnum, -1, 0 }; 

    if (semop(semid, &operations, 1) < 0) 
     error(__func__); 
} 

void signalIt(int semid, int semnum) 
{ 
    struct sembuf operations = { semnum, 1, 0 }; 

    if (semop(semid, &operations, 1) < 0) 
     error(__func__); 
} 

int main(void) 
{ 
    int i, semID, memID, good, bad; 
    char *memAddress; 

    if ((semID = semget(0x1001, 0, 0)) < 0) 
     error("Unable to get semaphores"); 

    if ((memID = shmget(0x1001, 0, 0)) < 0) 
     error("Unable to create shared memory"); 
    memAddress = shmat(memID, NULL, 0); 
    if (memAddress == NULL || memAddress == ((void *) -1)) 
     error("Unable to attach shared memory"); 

    good = 0; 
    bad = 0; 
    for (i = 0; i < 100; i++) 
    { 
     memAddress[0] = i; 
     signalIt(semID, REQUEST_SEM); 

     waitForIt(semID, RESPONSE_SEM); 
     if (memAddress[0] == 0x55) 
      good++; 
     else 
      bad++; 
    } 

    printf("good=%d bad=%d\n", good, bad); 

    if (shmdt(memAddress) < 0) 
     error("Unable to detach shared memory"); 
} 
相關問題