Problem with unnamed semaphore

Hi,

I’am testing Posix semaphores on Qnx. I get some troubles when I want to
wait an unnamed semaphore in a child process. Sem_wait returns -1 and errno
is set to 22 (EINVAL).

Could some one help me?

Thanx


Here is the code :

#include<unistd.h>
#include<semaphore.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/mman.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<signal.h>

void Process_Fils(void);

void Handler_SigInt(int sig);

/* DECLARATIONS POUR L’UTILISATION D’UN SEMAPHORE NON NOMME */

sem_t sem,*ptr_sema = &sem;
int pshared = 1;
unsigned int value = 1;
int sem_val,*ptr_sem_val = &sem_val;

int ret_val;

int fils;

struct sigaction sig_act;

main()
{
struct timespec Time;
sig_act.sa_handler = Handler_SigInt;
ret_val = sigaction (SIGINT,&sig_act, 0);
if (ret_val == -1)
perror("\n\rMAIN : sigaction failed !!!");

/* ------------------------------------------------------------
CREATION D’UN SEMAPHORE NON NOMME
IDENTIFICATEUR : ptr_sema,
SHARED : pshared = TRUE,
VALEUR INITIALE : value = 1.
------------------------------------------------------------ */

ret_val = sem_init (ptr_sema, pshared, value);
if (ret_val == -1)
perror("\n\rMAIN : sem_open failed !!!");

fils = fork();
if (!fils)
{
Process_Fils();
}

while (1)
{
Time.tv_sec = 2;
Time.tv_nsec = 0;
nanosleep(&Time,NULL);

/* ------------------------------------------------------------
VALIDER UN SEMAPHORE
IDENTIFICATEUR : ptr_sema
------------------------------------------------------------ */

ret_val = sem_post (ptr_sema);
if ( ret_val == -1)
perror ("\n\rMAIN : sem_post failed !!!");
}
}


void Process_Fils (void)
{
int compteur = 0;
signal(SIGINT,SIG_IGN);
printf(“Ptr = %x\n”,ptr_sema);

while (1)
{

/* ------------------------------------------------------------
ATTENDRE UN SEMAPHORE
IDENTIFICATEUR : ptr_sema
------------------------------------------------------------ */

ret_val = sem_wait (ptr_sema);
printf(“errno = %d, ret_val = %d\n”,errno,ret_val);
if (ret_val == -1)
perror ("\n\rMAIN : sem_wait failed !!!");
compteur++;
printf("\nCompteur = %d",compteur);
}
}

void Handler_SigInt(int sig)
{

/* ------------------------------------------------------------
DESTRUCTION D’UN SEMAPHORE NON NOMME
IDENTIFICATEUR : ptr_sema.
------------------------------------------------------------ */

ret_val = sem_destroy (ptr_sema);
if ( ret_val == -1)
perror("\n\rMAIN : sem_unlink failed !!!");

kill(fils,SIGKILL);
exit(0);
}

Pano <j.deflorette@caramail.com> wrote:

Hi,

I’am testing Posix semaphores on Qnx. I get some troubles when I want to
wait an unnamed semaphore in a child process. Sem_wait returns -1 and errno
is set to 22 (EINVAL).

Could some one help me?

When you fork(), your child gets a copy of all the memory. The
semaphore object in the child is now a different semaphore object
than in the parent, and that one has not been initialized.

If you need to share semaphores between multiple processes (even
parent-child) the semaphore must be in a shared memory area.
(see shmem_open().)

Note: you can also use mutexes and condvars (pthread_mutex*,
pthread_cond*) between processes by putting the mutex or condvar
in shared memory.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

I have worked with unamed semaphore and child processes under True64 Unix
and it wasn’t necessary to create a shared memory.

I have tried with the shm under Qnx ad it works perfectly now… :slight_smile: But
what is the use of the pshared argument of sem_init then?

“David Gibbs” <dagibbs@qnx.com> a écrit dans le message news:
b5ndc8$2ui$2@nntp.qnx.com

Pano <> j.deflorette@caramail.com> > wrote:
Hi,

I’am testing Posix semaphores on Qnx. I get some troubles when I want
to
wait an unnamed semaphore in a child process. Sem_wait returns -1 and
errno
is set to 22 (EINVAL).

Could some one help me?

When you fork(), your child gets a copy of all the memory. The
semaphore object in the child is now a different semaphore object
than in the parent, and that one has not been initialized.

If you need to share semaphores between multiple processes (even
parent-child) the semaphore must be in a shared memory area.
(see shmem_open().)

Note: you can also use mutexes and condvars (pthread_mutex*,
pthread_cond*) between processes by putting the mutex or condvar
in shared memory.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Hercot Jean-Yves <fa063821@skynet.be> wrote:

I have tried with the shm under Qnx ad it works perfectly now… > :slight_smile: > But
what is the use of the pshared argument of sem_init then?

If there is extra work that needs to be done in initializing or setting
up a semaphore such that it can be used between different processes,
rather than between threads in the same process, then the OS is
requested to do that extra initialization.

(Or, if you put it in a shared memory, and try to use it between
different processes, and don’t set this flag, then the behaviour
is undefined.)

I have worked with unamed semaphore and child processes under True64 Unix
and it wasn’t necessary to create a shared memory.

Our docs specifically mention shared memory in the docs for sem_init():

If the pshared argument is nonzero, then the semaphore can be shared
between processes via shared memory.

(of sem_init( sem_t *sem, int pshared, unsigned value); )

POSIX says:
If the pshared argument has a non-zero value, then the semaphore is
shared between processes; in this case any process that can access
the semaphore sem can use sem for performing sem_wait, … operations.

Only sem itself may be used for performing synchronization. The
result of referring to copies of sem in calls to sem_wait,… is
undefined.

So, True64 Unix has chosen to allow references to copies of the sem
to work, while we have not done so. (And, have documented in our
documentation how you must use it.)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Thank you very for this complete reply. In fact I’am testing Posix on Qnx
to see if we can replace True64 Unix with Qnx (-> I try to see wich OS is
closer with Posix specs)

→ Qnx 1 point - True64 0 point :slight_smile:

“David Gibbs” <dagibbs@qnx.com> a écrit dans le message de news:
b5nt8t$d3f$1@nntp.qnx.com

Hercot Jean-Yves <> fa063821@skynet.be> > wrote:

I have tried with the shm under Qnx ad it works perfectly now… > :slight_smile:
But
what is the use of the pshared argument of sem_init then?

If there is extra work that needs to be done in initializing or setting
up a semaphore such that it can be used between different processes,
rather than between threads in the same process, then the OS is
requested to do that extra initialization.

(Or, if you put it in a shared memory, and try to use it between
different processes, and don’t set this flag, then the behaviour
is undefined.)

I have worked with unamed semaphore and child processes under True64
Unix
and it wasn’t necessary to create a shared memory.

Our docs specifically mention shared memory in the docs for sem_init():

If the pshared argument is nonzero, then the semaphore can be shared
between processes via shared memory.

(of sem_init( sem_t *sem, int pshared, unsigned value); )

POSIX says:
If the pshared argument has a non-zero value, then the semaphore is
shared between processes; in this case any process that can access
the semaphore sem can use sem for performing sem_wait, … operations.

Only sem itself may be used for performing synchronization. The
result of referring to copies of sem in calls to sem_wait,… is
undefined.

So, True64 Unix has chosen to allow references to copies of the sem
to work, while we have not done so. (And, have documented in our
documentation how you must use it.)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Pano <j.deflorette@caramail.com> wrote:

Thank you very for this complete reply.

You’re quite welcome.

In fact I’am testing Posix on Qnx
to see if we can replace True64 Unix with Qnx (-> I try to see wich OS is
closer with Posix specs)

→ Qnx 1 point - True64 0 point > :slight_smile:

While I would like to see QNX win, this is actually:

QNX 1 point, True64 1 point, test code 0 point.

Both our, and True64’s implementation are quite valid – since both
are playing in the “undefined” area of POSIX. It is just that the
code that was written under True64 (and worked there) was a poor
test since it relied on undefined behaviour to work.

-David


“David Gibbs” <> dagibbs@qnx.com> > a écrit dans le message de news:
b5nt8t$d3f$> 1@nntp.qnx.com> …
Hercot Jean-Yves <> fa063821@skynet.be> > wrote:

I have tried with the shm under Qnx ad it works perfectly now… > :slight_smile:
But
what is the use of the pshared argument of sem_init then?

If there is extra work that needs to be done in initializing or setting
up a semaphore such that it can be used between different processes,
rather than between threads in the same process, then the OS is
requested to do that extra initialization.

(Or, if you put it in a shared memory, and try to use it between
different processes, and don’t set this flag, then the behaviour
is undefined.)

I have worked with unamed semaphore and child processes under True64
Unix
and it wasn’t necessary to create a shared memory.

Our docs specifically mention shared memory in the docs for sem_init():

If the pshared argument is nonzero, then the semaphore can be shared
between processes via shared memory.

(of sem_init( sem_t *sem, int pshared, unsigned value); )

POSIX says:
If the pshared argument has a non-zero value, then the semaphore is
shared between processes; in this case any process that can access
the semaphore sem can use sem for performing sem_wait, … operations…

Only sem itself may be used for performing synchronization. The
result of referring to copies of sem in calls to sem_wait,… is
undefined.

So, True64 Unix has chosen to allow references to copies of the sem
to work, while we have not done so. (And, have documented in our
documentation how you must use it.)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.


QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Gibbs <dagibbs@qnx.com> wrote:

Pano <> j.deflorette@caramail.com> > wrote:
Thank you very for this complete reply.

You’re quite welcome.

In fact I’am testing Posix on Qnx
to see if we can replace True64 Unix with Qnx (-> I try to see wich OS is
closer with Posix specs)

→ Qnx 1 point - True64 0 point > :slight_smile:

While I would like to see QNX win, this is actually:

QNX 1 point, True64 1 point, test code 0 point.

Both our, and True64’s implementation are quite valid – since both
are playing in the “undefined” area of POSIX. It is just that the
code that was written under True64 (and worked there) was a poor
test since it relied on undefined behaviour to work.

-David

OK. One more point for QNX/Dave for honesty.

QNX 2 point, True64 1 point