我正在尝试在Solaris 5.10计算机上使用名为semaphores的C ++ POSIX(即sem_open(),sem_wait(),sem_post())。目标是创建一个银行服务器程序,它可以同时接受许多客户端连接,并执行请求的事务。我接受每个请求,然后分叉一个子进程来维护该连接。赋值的目的是将这些进程与信号量和共享内存同步。我的程序结构如下:
#define BALANCE_SEM "/balance_sem"
// listen on a port and other stuff
static int64_t *balance = (int64_t *) mmap(NULL, sizeof(*balance), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
sem_t *balance_lock;
if ((balance_lock = sem_open(BALANCE_SEM, O_CREAT, 0644, 1)) == SEM_FAILED) {
fprintf(stderr, "ERROR: unable to initialize semaphore: %s\n", strerror(errno));
}
while (1) {
// accept request from client
int pid = fork();
// child process
if (pid == 0) {
sem_t *balance_sem;
if ((balance_sem = sem_open(BALANCE_SEM, 0)) == SEM_FAILED) {
fprintf(stderr, "ERROR: unable to open existing named semaphore: %s\n", strerror(errno));
}
transaction t = getTransactionFromClient();
switch (t.type) {
case 0:
if (sem_wait(balance_sem) < 0) {
fprintf(stderr, "ERROR: failed to wait on semaphore: %s\n", strerror(errno));
}
*balance = *balance + t.amount;
sem_post(balance_sem);
case 1:
if (sem_wait(balance_sem) < 0) {
fprintf(stderr, "ERROR: failed to wait on semaphore: %s\n", strerror(errno));
}
*balance = *balance - t.amount;
sem_post(balance_sem);
}
// parent process
} else {
// do some other stuff
}
}
有趣的是,当我在Linux机器上运行服务器程序时,一切都有效(我已尝试了几个)。但是,当我在Solaris机器上运行服务器程序时,我的错误消息将打印在sem_wait()调用上(但不会在sem_open())调用上,并且strerror(errno)返回“Invalid argument”。可能有什么不对?
编辑:
实际上,使用以下极其简化的代码会发生同样的错误,根本不需要分叉:
sem_t *balance_lock;
if ((balance_lock = sem_open(BALANCE_SEM, O_CREAT, 0644, 1)) == SEM_FAILED) {
fprintf(stderr, "ERROR, unable to initialize semaphore: %s\n", strerror(errno));
}
if (sem_wait(balance_lock) < 0) {
fprintf(stderr, "ERROR, failed to wait on semaphore: %s\n", strerror(errno));
}