2014-12-06 111 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"); 
} 
相关问题