对于家庭作业,我需要使用 IPC。我为共享内存编写了一些代码,但它无法按我的意愿工作。我希望服务器进程在客户端之前运行。我做错了什么?如何解决?
//main.cpp
#include "stockexchangeserver.h"
#include "stockexchangeclient.h"
#include <semaphore.h>
int main(int argc,char *argv[])
{
StockExchangeServer server;
StockExchangeClient client;
pid_t pid;
sem_t sem;
int pshared = 1;
unsigned int value = 0;
sem_init(&sem,pshared,value);
if ((pid = fork()) < 0) {
std::cout<<"fork error\n";
} else if (pid > 0) {
sem_wait(&sem);
client.start2();
sem_post(&sem);
} else {
server.start2();
sem_post(&sem);
}
return 0;
}
//stockexchangeclient.cpp
void StockExchangeClient::start2() {
int sharedMemoryId;
key_t key;
int *shm;
key = 6000;
if((sharedMemoryId = shmget(key,sizeof(int),0666)) < 0) {
std::cout<<"Shared memory create error\n";
exit(1);
}
else{}
if((shm = (int *)shmat(sharedMemoryId,NULL,0)) == (int *)-1) {
std::cout<<"Shared memory attach error\n";
exit(1);
}
else{}
*shm = 1;
exit(0);
}
//stockexchangeserver.cpp
void StockExchangeServer::start2()
{
int sharedMemoryId;
key_t key;
int *shm;
key = 6000;
if((sharedMemoryId = shmget(key,sizeof(int),IPC_CREAT | 0666)) < 0) {
std::cout<<"Shared memory create error\n";
exit(1);
}
else{}
if((shm = (int *)shmat(sharedMemoryId,NULL,0)) == (int *)-1) {
std::cout<<"Shared memory attach error\n";
exit(1);
}
else{}
*shm = 0;
while(*shm == 0) {
sleep(1);
}
std::cout<<"Shared memory succeded\n";
}
最佳答案
我对此进行了测试,实际上服务器进程首先运行(StockExchangeServer::start2
)但问题出在
while(*shm == 0) {
sleep(1);
}
这会导致无限循环,并且您没有机会让 StockExchangeClient::start2()
更改 *shm
,因为父级正在无限期地等待 sem_wait
因为 child 从未执行过 sem_post
相反,可以在进入 StockExchangeServer::start2
中的循环之前执行 sem_post
,以便您从其 sem_wait
中释放父级。为此,您需要将 &sem
发送到 StockExchangeServer::start2
。可能是通过将其原型(prototype)更改为类似 StockExchangeServer::start2( sem_t *sem )
的东西。
但由于 sem
是一个未命名的信号量,并且存在 2 个拷贝,一个在父级中,一个在子级中,如果您希望父级和子级都使用它,您需要使用 shmget
在共享内存区域中创建它,然后跨进程访问它。如果您不想要所有这些痛苦,您可以切换到命名信号量,它甚至可以被不相关的进程访问。 简而言之,未命名信号量通常用于线程(因为线程共享数据),而命名信号量用于进程。
此外,正如 David Schwartz 在评论中所观察到的,确保防止对 while
循环进行意外优化。比方说,在循环之前打印出 shm
的值。
关于c++ - 与信号量共享内存同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9783982/