我有一个信号量问题,我虽然你可以帮助我.. 好的,首先让我展示我在做什么。 我需要c程序,一个服务器和其他命名客户端。
在服务器上我这样做:
#ifdef _SEM_SEMUN_UNDEFINED //here I define semun, in case that is not defined
#undef _SEM_SEMUN_UNDEFINED
union semun {
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
#endif
union semun semopts;
int semID;
semID = semget(1000, 1, 0600 | IPC_CREAT | IPC_EXCL); //I want this gives error, if there is already a sem on that key
if(semID < 0){
perror(semID);
exit(1);
}
semopts.val = 10;
semctl(semID, 0, SETVAL, semopts); //Here I set the val for the first sem of the group, I want it with value 10
好的,这是我的服务器文件,现在客户端,我需要做的是:
10个客户端可以同时读取内存,所以对于每个读者,我在sem上做-1。 1个客户端可以同时在内存上写入并且没有人可以读取,所以在这种情况下,我在sem上做-10,对吧?
所以这是我的客户端程序:
struct sembuf UP10 = {0, 10, 0};
struct sembuf DOWN10 = {0, -10, 0};
struct sembuf UP1 = {0, 1, 0};
struct sembuf DOWN1 = {0, -1, 0};
int semID;
semID = semget(1000, 1, 0600 | IPC_CREAT);
if(semID < 0){
perror(semID);
exit(1);
}
//Okay now its here on my switch where they read or write
switch(selection[0]){ //This store the number from a scanf
case '1':
semop(semID, &DOWN1, 1);
functionToRead(..);
semop(semID, &UP1, 1);
break;
case '2': //Here the client also read from memory
semop(semID, &DOWN1, 1);
functionToReadAlsoMemory(...);
semop(semID, &UP1, 1);
break;
case '3': //Here is the block where the client WRITES on memory so use the struct DOWN10 and UP10
semop(semID, &DOWN10, 1);
functionToWriteOnMemory(...);
semop(semID, &UP10, 1);
break;
}
好的,问题是:
当我按3(块写入内存)时,程序在sem上执行-10,然后输入该函数,有scanf,所以sem将为0,直到退出函数..当用户按下enter键时并通过scanf。 在这种情况下,如果客户端正在写入并且我尝试打开另一个客户端并写入,它会一直等到另一个客户端离开该函数并执行sem UP10。好吧,好吧,那就是我想要的,然后等待的客户端通过该功能写出来......好的
但是如果一个客户端在该功能上(该客户端执行DOWN10,那么sem 0),并且我尝试从内存中读取(在情况'1'或情况'2'),他可以执行!但不应该!! 因为如果sem仍然是0,他就不能让sem DOWN1,对吧?
我猜你们在这里理解我的问题,我有sem的包含等等,问题不存在,对吧?因为它适用于2个尝试写的客户..
如果你们弄清楚我的问题在哪里,那将是非常好的:s 非常感谢,欢呼!!
答案 0 :(得分:0)
信号量是一种很难用于普通用户空间代码的低级工具。请考虑使用POSIX的控制结构pthread_mutex_t
和pthread_cond_t
。如今,它们可以很容易地在进程之间的共享内存中使用。
信号量的一个主要问题是,任何类型的信号都可能中断调用,特别是如果IO被传递到您的进程。您必须捕获调用提供的返回值和错误代码,然后再次等待。