I have one problem with semaphores, I though you could help me..
Okay first off let me show what I am doing.
I have to c programs, one server and other named client.
On server I do this:
#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
Okay this is my server file, now on client, what I need to do is:
10 clients can read from memory at same time, so for each reader I do -1 on the sem.
1 client can write on memory at same time and no one can read, so in this case, I do -10 on the sem, right??
So here is my client program:
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;
}
Okay so the problem is :
when I press 3 (block to write on memory), program does -10 on sem, and enter on that function, there are scanf, so the sem will have 0 till it exits from the function.. when user presses enter and goes through the scanf.
In this case, if on client is writing and I try to open another client and write, it keeps waiting till the other client leaves the function and does the sem UP10. OKAY its good, thats what I want, and then the client that was waiting goes through that function to write.. OKAY GOOD
But if one client is on that function (that client did DOWN10, so sem 0), and I try to read from memory (on case ‘1’ or case ‘2’), he ACTUALY can! But should not!!
Because if sem is still on 0, he cannot make sem DOWN1, right??
I guess you guys understood my problem here, I have the includers for sem and such, the problem is not there, right? because it works for 2 clients trying to write..
Would be really nice if you guys figured out where is my problem :s
Thanks alot in advance, cheers!!
Semaphores are a difficult tool that are much too low-level for normal userspace code. Consider using POSIX’ control structures
pthread_mutex_tandpthread_cond_t, instead. They can easily be used in shared memory between processes, nowadays.One of the main problems with semaphores is that the calls can be interrupted by any kind of signal, in particular if IO is delivered to your process. You’d have to capture the return value and error codes that the calls provide, and then go into waiting again.