Semaphore in C for shared memory can't initialize - c

The command semctl always returns -1 (returns "Fail2" in console). What am I doing wrong?
union semun{
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
} forsem;
forsem.val = 0;
int sem;
if((sem= semget(key, 1, 0666 | IPC_CREAT) == -1)) {
fprintf(stderr, "Fail1");
}
if (semctl(sem, 0, SETVAL, forsem) == -1) {
fprintf(stderr, "Fail2");
}
Errno writes Invalid argument

You make a simple mistake: in
if((sem= semget(key, 1, 0666 | IPC_CREAT) == -1)) {
fprintf(stderr, "Fail1");
}
You should write
if((sem= semget(key, 1, 0666 | IPC_CREAT)) == -1) {
fprintf(stderr, "Fail1");
}
Notice the brackets?
By the way, the error is EIDRM because sem is 0 in your code, not Invalid Argument.

Thanks for your answer! It does not matter. The only thing it's not giving error is for semctl with the second argument 0 (number of the semaphore in the semaphore set), if I put 1 or 30 there, it returns -1.

Related

shmat() - perror returns invalid argument

I tried to attach a char vector to a shared memory: shmget() is ok but shmat() returns an error.
This is my code:
...
...
#define TXTSZ 512
---main---
char *address;
int shm_id;
...
if(shm_id = shmget(IPC_PRIVATE, TXTSZ*sizeof(char), IPC_CREAT | 0666) == -1){
perror("Error shmget");
}
...
if((address = (char *)shmat(shm_id, NULL, 0)) == (char *) -1){
perror("Error shmat");
}
...
...
Classic mistake (usually made with open()). You're setting shm_id to the result of the comparison, not the ID returned by shmget.
You need parentheses around the assignment.
if((shm_id = shmget(IPC_PRIVATE, TXTSZ*sizeof(char), IPC_CREAT | 0666)) == -1){

c - semctl GETVAL can't read the semaphore value

I'm working on a project for my university so I can't use the semaphore.h library.
What I'm trying to do is having a semaphore initialized to a value MAX_ACCESS (default 10) and if that semaphore is available do things.
semId = semget(SEM_KEY, 1, IPC_CREAT | 0666);
if (semId == -1) errExit("semget 1");
if (initSem(semId, 0, MAX_ACCESS) == -1) errExit("initSem");
initSem() is defined as follow:
int initSem(int semId, int semNum, int val) {
union semun arg;
arg.val = val;
return semctl(semId, semNum, SETVAL, arg);
}
And as far as I can tell it works as intended. It sets the semaphore value to 10.
Just to post everything, semun is:
union semun {
int val;
struct semid_ds* buf;
unsigned short* array;
#if defined(_linux_)
struct seminfo* _buf;
#endif
};
What causes me problem is the function semAvailable()
int semAvailable(int semId, int semNum) {
union semun arg;
if (semctl(semId, semNum, GETVAL, arg) == -1) errExit("semAvailable: semctl");
return (arg.val > 0);
}
This function should get the value of the semaphore and return if it's available (greater than zero). Although right after initSem() when I use semAvailable() as a condition, it always return 0.
if (semAvailable(semId, 0)) {
/*do things*/
}
So I tried to print the value of arg.val in semAvailable and it prints zero, then I tried printing it inside initSem, right after calling a semctl(semid, 0, GETVAL, arg) and it printed the correct value, at last I tried calling a semctl() in the main program right after the initSem() and I printed the value of arg.val, and it printed the value of the variable initialized.
if (initSem(semId, 0, MAX_ACCESS) == -1) errExit("initSem");
arg.val = 0;
semctl(semId, 0, GETVAL, arg);
printf("Semctl val: %d\n", arg.val); /*This print 0*/
Why the value of the semaphore is not getting stored in arg.val after the semctl? Am I missing something obvious?
Value of semaphore is the return value of function semctl using GETVAL command.
int semValue = semctl(semId, 0, GETVAL, arg);
printf("Semctl val: %d\n", semValue);
You cannot expect that a function that has not parameter passed by address (pointers) could return a value into a variable passed by value..
HERE you can find a complete example of all commands of semctl function.

Semaphore counter: program hangs

I want create a semaphore counter, with this code:
union semun arg_assistant;
int max_ass = atoi(argv[1]);
printf("Num massimo di assistant %d\n", max_ass);
fflush(stdout);
if ((sem_a = semget(IPC_PRIVATE, 1, 0600)) == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
arg_assistant.val = max_ass;
if (semctl(sem_a, 0, SETALL, arg_assistant) == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
When I executed my program, I have no errors but it hangs and it don't create this sem. Any suggestion about what could be the problem? Have I make some mistake with falgs?
Thaks
From documentation
SETALL
Set semval for all semaphores of the set using arg.array,
For SETALL you need array of values
unsigned short int sem_array[1] ;
sem_array[0] = max_ass;
arg_assistant.array = sem_array;
if (semctl(sem_a, 0, SETALL, arg_assistant) == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
sem_array[1] becaues you create only one semaphore.

semaphore initialization in c

arg.val = 1;
if (sem_id = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT) == -1 ){
perror("Creating semaphore failed");
exit(1);
}
else {
printf("Creating a semaphore with ID: %d \n",sem_id);
if (semctl(sem_id, 0, SETVAL, arg) == -1 ) {
perror("Initialization of semaphore failed\n");
exit(1);
}
}
I am trying to create and initialize a semaphore and when I am compiling my program it returns me:
"Initialization of semaphore failed
:Identifier removed
Could you explain me the reason why this happens??
if (sem_id = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT) == -1 )
is parsed (because == binds stronger than =)
if (sem_id = (semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT) == -1) )
you probably want
if ((sem_id = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT)) == -1 )
The operation == has a higher precedence than the operation =. I believe this means this means that sem_id is getting set to a true value. You should group the operation in the if statement.
if((sem_id = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT)) == -1){

Locking semaphores in C problem sys/sem

EDIT: This peace of code is pretty fine (so take it as example of semaphores ;). Bug in my program was in another place - found by my friend.
I have problem with my functions. Sometimes two processes enter into critical section. I can't find problem in this after I spent 10 hours by debugging. On what I should aim? Is there any possibility to have bud in this piece of code?
// lock semaphore
static int P(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1; /* P() */
sem_b.sem_flg = 0;
if (semop(sem_id, &sem_b, 1) == -1) {
// error
return(0);
}
return(1);
}
// unlock semaphore
static int V(int sem_id)
{
struct sembuf sem_b[1];
sem_b.sem_num = 0;
sem_b.sem_op = 1; /* V() */
sem_b.sem_flg = 0;
if (semop(sem_id, &sem_b, 1) == -1) {
// error
return(0);
}
return(1);
}
static int set_semval(int sem_id) {
// set to 1 (opened semaphore)
if (semctl(sem_id, 0, SETVAL, 1) == -1) {
// error
return(0);
}
return(1);
}
static int get_val(int sem_id)
{
union semun sem_union;
//sem_union.val = 0; ?
return semctl(sem_id, 0, GETVAL, sem_union);
}
The action loop:
// semaphores init
int mutex;
if ((mutex=semget(key+2, 1, 0666))>=0) {
// semaphore exists
fprintf(stderr,"semaphore exists for key %d\n", key+2);
}
if ((mutex=semget(key+2, 1, 0666 | IPC_CREAT)) == -1) {
exit(EXIT_FAILURE);
}
if (!set_semval(mutex)) {
exit(EXIT_FAILURE);
}
fork() // some times with good conditionals
// in some children
while(1) {
P(mutex);
assert(get_val(mutex)==0); // always ok
action(); // sometimes made by two processes at same time - fault
V(mutex);
}
Pls, feel free to edit my question.
Many thanks
in your 'action loop' what do you do if your semaphore does not exist?
currently your 3rd parameter to semget is 0666 or the PERMISSION_RW constant. You may want to use:
shmget(key, 1, PERMISSION_RW | IPC_CREAT);
this way if your semaphore does not exist it will create one.
So bug was at another place...

Resources