共享内存与信号量同步
Shared memory synchronization with semaphores
对于家庭作业,我需要使用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 errorn";
} 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 errorn";
exit(1);
}
else{}
if((shm = (int *)shmat(sharedMemoryId,NULL,0)) == (int *)-1) {
std::cout<<"Shared memory attach errorn";
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 errorn";
exit(1);
}
else{}
if((shm = (int *)shmat(sharedMemoryId,NULL,0)) == (int *)-1) {
std::cout<<"Shared memory attach errorn";
exit(1);
}
else{}
*shm = 0;
while(*shm == 0) {
sleep(1);
}
std::cout<<"Shared memory succededn";
}
我对此进行了测试,事实上服务器进程首先运行(StockExchangeServer::start2
),但问题出在中
while(*shm == 0) {
sleep(1);
}
这导致了一个无限循环,并且您没有给StockExchangeClient::start2()
更改*shm
的机会,因为父级在sem_wait
无限期等待,因为子级从未执行sem_post
相反,可以在进入StockExchangeServer::start2
中的循环之前执行sem_post
,以便从其sem_wait
中释放父级。为此,您需要将&sem
发送到StockExchangeServer::start2
。可能是通过将其原型更改为类似StockExchangeServer::start2( sem_t *sem )
的东西。
但是,由于sem
是一个未命名的信号量,并且存在两个副本,一个在父级,一个位于子级,如果您希望父级和子级都使用它,则需要使用shmget
在共享内存区域中创建它,然后跨进程访问它。如果您不想所有这些痛苦,您可以切换到命名信号量,甚至可以由不相关的进程访问简而言之,未命名信号量通常用于线程(因为线程共享数据),而命名信号量用于进程
正如David Schwartz在评论中所观察到的,确保防止while
循环的意外优化。例如,在循环之前打印出shm
的值。
相关文章:
- 删除旧的信号量系统V
- 父进程和子进程之间的 POSIX 信号量
- 访问共享内存而不使用易失性、std::atomic、信号量、互斥锁和自旋锁
- 多线程.如果我使用信号量,我可以在开始时创建很多线程还是应该只有几个线程?
- C/C++ - 用于按顺序打印数字的 sem_t 类型的单个信号量
- 单车道桥 使用信号量进行同步
- 用于 64 位/32 位 IPC 的 POSIX 信号量的替代方案?
- 这个餐饮哲学家问题(dpp)的解决方案是如何工作的?互斥体和信号量
- 发布信号量返回错误 6(无效句柄)
- 在 C Linux 中使用三个线程使用信号量同步按顺序打印 3 4 5 50 次
- 在使用 pthread 和信号量实现生产者-消费者问题时需要帮助
- 如何让一个线程继续,而另一个线程正在等待C++中的信号量
- 实现信号量
- 计算信号量还是互斥体?
- POSIX 信号量在高争用/负载下不起作用
- C++:提升:托管共享内存是否需要信号量锁
- 信号量的问题
- 如何使用Windows API直接将进程"assign"到信号量?
- 从主线程C++更新信号量
- 共享内存与信号量同步