【发布时间】:2016-05-31 08:48:35
【问题描述】:
我有一个使用信号量的客户端服务器项目。 我从同一个文件夹运行两者,它们使用相同的密钥。 现在,我希望服务器锁定信号量,因此客户端在服务器释放它之前无法运行命令,但客户端忽略服务器的锁定。我不明白我的错误在哪里。服务器代码:
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
#include <sys/stat.h>
#define FLAGS IPC_CREAT | 0644
union semun {
int val;
struct semid_ds *buf;
ushort *array; };
union semun semarg;
struct sembuf sops[1];
int main() {
semarg.val=1;
int resultsCreator=open("results.txt",O_CREAT|O_RDWR);
key_t key;
key = ftok("results.txt", 'k');
int shmid = shmget(key, 12, FLAGS);
int semfor = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666);
semctl ( semfor , 0 , SETVAL , semarg );
sops->sem_num = 0;
sops->sem_flg = 0;
sops->sem_op = -1;
int k = semop ( semfor , sops , 1 ); //lock the semaphore
char* shmaddr;
int numWaiting =0;
while(1){
sleep(2); //CHECK EVERY 2 SECONDS IF SOMEONE IS WAITING
numWaiting = semctl(semfor, 0, GETNCNT, semarg);
if(numWaiting==0){
printf("none waiting\n");
continue; }
printf("more than one waiter\n"); //NEVER GETS HERE
} //END WHILE
客户端代码:
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
#include <sys/stat.h>
#define FLAGS IPC_CREAT | 0644
union semun {
int val;
struct semid_ds *buf;
ushort *array;
};
union semun semarg;
struct sembuf sops[1];
int main()
{
key_t key;
key = ftok("results.txt", 'k');
int shmid = shmget(key, 12, FLAGS);
semarg.val=1;
int semfor = semget(key, 0, 0666);
semctl ( semfor , 0 , SETVAL , semarg );
sops->sem_num = 0;
sops->sem_flg = 0;
sops->sem_op = -1;
semop ( semfor , sops , 1 );
printf("skipped lock\n"); //PRINTS IT, EVEN WHEN IT'S STILL LOCKED
sops->sem_op = 1;
semop ( semfor , sops , 1 );
return 0;
}
为什么客户端会忽略服务器的信号量锁?
【问题讨论】:
-
真实代码是否也漏掉了任何错误检查?
-
/我删除了一些不重要的部分以使其尽可能短,但我的代码没有错误,我在这里展示了它打印的内容
-
我删除了一些不重要的部分 如果你不知道它为什么不起作用,你就无法知道哪些部分是不重要的。打印
semget()的返回值 - 每次运行它。 -
我对每个系统调用都有这个检查,我删除了它,因为它从不指向错误(从不返回 -1)
-
保留代码中的所有错误检查,让它只在发生错误时向
stderr输出消息。