PDA

View Full Version : processes semaphore



np2k
06-15-2010, 12:42 PM
Hi all.
I want compile my program that uses semaphore for processes with the posix standard...but if I compile my program with:


gcc -o myprogram myprogram.c

I don't have the behavior of the posix semaphore.

Do you know any option for gcc?

MK27
06-15-2010, 12:49 PM
I don't have the behavior of the posix semaphore.


Presuming this is on a POSIX OS such as linux, yes you do. Why do you think you don't?

You need to use these headers, nb:


#include <sys/ipc.h>
#include <sys/sem.h>

np2k
06-15-2010, 01:01 PM
if i write:


man semop

i have this man:



SEMOP(2) Linux Programmer’s Manual SEMOP(2)

NAME
semop, semtimedop - semaphore operations

SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semop(int semid, struct sembuf *sops, unsigned nsops);

int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
struct timespec *timeout);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

semtimedop(): _GNU_SOURCE

DESCRIPTION
Each semaphore in a semaphore set has the following associated values:

unsigned short semval; /* semaphore value */
unsigned short semzcnt; /* # waiting for zero */
unsigned short semncnt; /* # waiting for increase */
pid_t sempid; /* process that did last op */
...


where there is a specification of semop different from the specification of posix.
in fact if i write


man 3 semop

i have:



SEMOP(P) POSIX Programmer’s Manual SEMOP(P)

NAME
semop - XSI semaphore operations

SYNOPSIS
#include <sys/sem.h>

int semop(int semid, struct sembuf *sops, size_t nsops);

DESCRIPTION
The semop() function operates on XSI semaphores (see the Base Definitions volume of IEEE Std 1003.1-2001, Section 4.15,
Semaphore). It is unspecified whether this function interoperates with the realtime interprocess communication facilities
defined in Realtime .

The semop() function shall perform atomically a user-defined array of semaphore operations on the set of semaphores associated
with the semaphore identifier specified by the argument semid.

The argument sops is a pointer to a user-defined array of semaphore operation structures. The implementation shall not modify
elements of this array unless the application uses implementation-defined extensions.
....


and I'm interested in this!

MK27
06-15-2010, 08:41 PM
and I'm interested in this!

You're in luck, that's what I was referring to. You do not need to use any switches or link to anything via gcc. Just #include the headers.

np2k
06-16-2010, 02:35 AM
no...i'm not in luck...
when i program the software with semaphore i don't have the behavior described in the second man pages...
the behavior of the semaphore. more precisely, of
semop function meets the specifications of the first man page!!
You understand? :(

MK27
06-16-2010, 06:08 AM
Hmm. The man page I found most useful when doing semaphore programming was this one:

semop (http://www.opengroup.org/onlinepubs/9699919799/functions/semop.html)

Which looks to me to be identical to the man 3 page (so I can attest to the fact that the linux implementation does work this way). The Open Group are POSIX, that site is the POSIX standard.

I did not closely compare them, but these (man 2 and man 3) look more or less identical to me, the only thing that jumped out at me was that struct sembuf sem_id is specifically unsigned in the linux page. I do not think this matters.

Also, semval (for example) is not explicitly defined in the POSIX page -- it just says "see <sys/sem.h>", whereas sem.h is quoted specifically in the linux page. However, if you look at the online version of man 3 via that link you'll notice it's "see <sys/sem.h> (http://www.opengroup.org/onlinepubs/9699919799/basedefs/sys_sem.h.html)" wherein semval is defined exactly as it is in the linux page.

Anyway, that's the limit of my experience. If you know more than me and there is some specific incompatibility between the POSIX standard and the linux implementation, please let me know!

If not, I think they are two different descriptions of the same thing. Obviously, the linux one is more specific because it is a real implementation and not a standard governing the parameters of such. I found the POSIX page more helpful, tho, and you can use just that. If you haven't done any semaphore programming, pay particular attention to this:



The variable sem_op specifies one of three semaphore operations:

1. If sem_op is a negative integer and the calling process has alter permission, one of the following shall occur:

* If semval(see <sys/sem.h>) is greater than or equal to the absolute value of sem_op, the absolute value of sem_op is subtracted from semval. Also, if (sem_flg &SEM_UNDO) is non-zero, the absolute value of sem_op shall be added to the semadj value of the calling process for the specified semaphore.

* If semval is less than the absolute value of sem_op and (sem_flg &IPC_NOWAIT) is non-zero, semop() shall return immediately.

* If semval is less than the absolute value of sem_op and (sem_flg &IPC_NOWAIT) is 0, semop() shall increment the semncnt associated with the specified semaphore and suspend execution of the calling thread until one of the following conditions occurs:


I just wanted to emphasize that the absolute value (a positive integer) of sem_op is used there, this threw me for a loop initially.

np2k
06-17-2010, 01:02 PM
MK27...you were in right...
it's my fault. the problem is another!!!!



#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>


//A = 1,2,1 ---- B = 3,0,5

union semun {
int val;
struct semid_ds* buf;
unsigned short int* array;
struct seminfo* __buf;
};

int main()
{
int sem_id;
union semun argument;
unsigned short values[3];

sem_id = semget(IPC_PRIVATE, 3,
IPC_CREAT |IPC_EXCL |S_IRUSR | S_IWUSR);

values[0] = 1;
values[1] = 1;
values[2] = 0;

argument.array = values;

semctl(sem_id,0,SETALL,argument);
semctl(sem_id,1,SETALL,argument);
semctl(sem_id,2,SETALL,argument);

struct sembuf operations[3];
operations[0].sem_num = 0;
operations[0].sem_op = -1;
operations[0].sem_flg = 0;

operations[1].sem_num = 1;
operations[1].sem_op = -2;
operations[1].sem_flg = 0;

operations[2].sem_num = 2;
operations[2].sem_op = -1;
operations[2].sem_flg = 0;

semop(sem_id,operations,1);

printf("after...\n")

union semun ignored_argument;
semctl (sem_id, 1, IPC_RMID, ignored_argument);

return 0;
}


the answer is: why the program prints "after"? why semop doesn't block the process?
the values of semaphore is:
1 1 0
but the operations is, respectly
-1 -2 -1

so: 1-1 = 0 OK, but 1-2 <0 KO => blocked!
but i have the "after" string....

jeffcobb
06-17-2010, 10:04 PM
This: Semaphores in Linux - O'Reilly Media (http://linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html) might help.

np2k
06-18-2010, 02:03 AM
i've found the problem...
the right line of semop functions is:


semop(sem_id,operations,3)


because the last argument nsops is the number of sembuf structures in the array!
i.e.


nsops:
Determines how many sembuf you are passing. The nsops argument is provided in case
the operation needs to be performed on bunch of semaphores at one time.


thank you jeffcobb