我有程序A和程序B.程序A使用shmget创建一个存储到共享内存中的队列,然后是shmat。进程B启动,然后使用相同的shmid获得进程A在没有问题的情况下生成的队列。进程A(A和B都明显在同一时间运行),然后运行修改队列中某个元素的方法。当程序A这样做时,指向该内存块的指针给我一个分段错误。可能是因为程序B现在有指向它的指针我想。 我的问题是我该如何解决这个问题,以便程序A可以编辑和读取队列以及程序B.我知道我需要某种锁,但不知道什么样的锁最好或者如何正确执行这个。如果你可以提供一些示例代码来解释你的解释,那将会有很大的帮助。我正在用C编写所有这些,并且进程A有两个键,一个用于队列,另一个用于存储程序B共享内存中分配的每个段的所有shmids,供程序B用来检索那个信息。如何在两个进程之间协调共享内存
1
A
回答
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");
}
相关问题
- 1. 在Dalvik中的两个进程之间共享内存
- 2. 如何在服务和用户进程之间共享内存?
- 3. 如何在两个Java Web服务之间共享内存?
- 4. 进程之间不共享共享内存
- 5. 如何在两个进程之间共享数据
- 6. 如何在两个进程之间共享COM对象?
- 7. 2个进程(应用程序)之间的共享内存
- 8. 如何在两个或多个程序之间共享内存中的System.Object?
- 9. 如何保护Linux中进程之间共享的内存
- 10. 在两个线程之间共享QAxObject?
- 11. 在多个进程之间协调对共享侦听套接字的接受
- 12. 在32位和64位进程之间共享共享内存段
- 13. 父进程和子进程共享一个IPC共享内存
- 14. 通过使用mmap在进程之间共享内存
- 15. 在所有PHP进程之间共享变量/内存
- 16. 共享内存进程间通信
- 17. 在多个进程之间共享共享对象
- 18. 如何在fork或子进程之后创建共享内存?
- 19. 进程VS线程:两个进程可以共享相同的共享内存吗?可以两个线程?
- 20. Android在两个进程之间共享SurfaceTexture
- 21. 在两个进程之间共享资源
- 22. 在两个进程之间共享全局变量
- 23. 在C#中的两个进程之间共享对象
- 24. 在Android中的两个进程之间共享JavaVM对象
- 25. 在Solaris中的父进程和子进程之间共享内存(在C中)
- 26. 在多进程之间共享进程之间的状态
- 27. 如何在两个ASP.NET应用程序之间共享应用程序缓存
- 28. 如何在java中的两个线程之间共享变量?
- 29. 如何在Java中的两个线程之间共享变量?
- 30. 如何在两个winform应用程序之间共享数据?
你可能不希望为您解决问题这种方式。如果你真的想得到很好的帮助,你应该说明你的根本问题。 – 2014-12-06 21:40:06
您将使用命名的(系统范围的)信号量/互斥量。这里有一个相关的讨论:http://stackoverflow.com/questions/8359322/how-to-share-semaphores-between-processes-using-shared-memory – Archie 2014-12-06 22:29:47