OVH Cloud OVH Cloud

[C] Les sémaphores

9 réponses
Avatar
TigrouMeow
Bonjour,

J'espère que je suis sur le bon NG... je suppose car les sémaphores font
partie du C standard non ? ...

Enfin bref, je passe à mon problème.

En gros, j'ai un sémaphore qui a une value de 1 initialement et j'ai des
threads autour qui veulent "le prendre".

Chaque thread tente de le prendre (en faisant un semop avec -1 dessus) sinon
attende de l'avoir disponible.
Le thread le "rends" au bout de 3sec avec un semop 1.

Voici le résultat que j'obtiens :

Le 1er ya arrive.
Le 2ème aussi ! (pas normal !!!! il devrait pas ya arriver...)
Le 3ème se met en attente.
Le 4ème se met en attente.

Le 1er libère.
.. à ce moment là rien ne se passe ... (pas normal!!!)
Le 2ème libère.
La ça prends le fonctionnement normal... c'est à dire que le 3 prends le
sémaphore, le rends ensuite et le 4 le prends, etc...

Voilà, j'ai essayé de faire explicite... c'est bizarre, c'est comme si le
1er thread se servait d'un autre sémaphore, pourtant c'est le même code que
les autres.
J'espère que vous verrez rapidement le problème, sinon j'exposerai mon code
si ça suffit pas.

Je vous remercie de votre aide :)

TigrouMeow

9 réponses

Avatar
DINH Viêt Hoà

Voilà, j'ai essayé de faire explicite... c'est bizarre, c'est comme si le
1er thread se servait d'un autre sémaphore, pourtant c'est le même code que
les autres.
J'espère que vous verrez rapidement le problème, sinon j'exposerai mon code
si ça suffit pas.


expose un code minimaliste.

--
DINH V. Hoa,

"dans la famille, on est tous intelligents" -- sunZ

Avatar
TigrouMeow
DINH Viêt Hoà wrote:


Voilà, j'ai essayé de faire explicite... c'est bizarre, c'est comme si le
1er thread se servait d'un autre sémaphore, pourtant c'est le même code
que les autres.
J'espère que vous verrez rapidement le problème, sinon j'exposerai mon
code si ça suffit pas.


expose un code minimaliste.



Alors une petite partie d'initialisation :

union semun uVal;

all->semid = semget(all->key, 1, 0006 | IPC_CREAT);
uVal.val = 1;
semctl(all->semid, 0, SETVAL, uVal);

Ensuite je lançe chacun de mes threads... la fonction des threads est celle
ci :

int res;
struct sembuf sem_oper;

sem_oper.sem_num == 0;
sem_oper.sem_op = -1;

res = semctl(all->semid, 0, GETVAL);

/* ON TENTE DE PRENDRE LA MAIN OU ON WAIT*/
semop(all->semid, &sem_oper, 1);
res = semctl(all->semid, 0, GETVAL);

sleep(3);

/* ON REND LA MAIN */
sem_oper.sem_op = 1;
semop(all->semid, &sem_oper, 1);
pthread_exit(NULL);

J'espère que vous verrez mon erreur là dedans...


Avatar
Encolpe DEGOUTE
Dans fr.comp.os.unix, TigrouMeow écrivit:
Bonjour,

J'espère que je suis sur le bon NG... je suppose car les sémaphores font
partie du C standard non ? ...


Non.
Il y a les threads POSIX et les threads Unix. Les différences sont
minimes dans les spécifications mais bien réelles lors de la
programmation.
Il y a un bon bouquin sur les threads Unix:
Programmer avec les threads Unix, Charles J. Northrup chez Thomson
publishing.

--
Encolpe DEGOUTE
http://colpi.info
Logiciels libres, hockey sur glace et autres activités cérébrales

Avatar
DINH Viêt Hoà

Il y a les threads POSIX et les threads Unix. Les différences sont
minimes dans les spécifications mais bien réelles lors de la
programmation.
Il y a un bon bouquin sur les threads Unix:
Programmer avec les threads Unix, Charles J. Northrup chez Thomson
publishing.


ou "Unix Network Programming - Volume II", de Richard Stevens,
dans toutes les bonnes salles. (Unix meurt à la fin)

--
DINH V. Hoa,

"dans la famille, on est tous intelligents" -- sunZ

Avatar
DINH Viêt Hoà

union semun uVal;

all->semid = semget(all->key, 1, 0006 | IPC_CREAT);


à quoi correspond 0006 ?

uVal.val = 1;
semctl(all->semid, 0, SETVAL, uVal);

Ensuite je lançe chacun de mes threads... la fonction des threads est celle
ci :

int res;
struct sembuf sem_oper;

sem_oper.sem_num == 0;


test d'égalité ou autre ?

sem_oper.sem_op = -1;


et la valeur du flag ?

res = semctl(all->semid, 0, GETVAL);

/* ON TENTE DE PRENDRE LA MAIN OU ON WAIT*/
semop(all->semid, &sem_oper, 1);
res = semctl(all->semid, 0, GETVAL);

sleep(3);

/* ON REND LA MAIN */
sem_oper.sem_op = 1;


tu ne dois pas indiquer un numéro de sémaphore à traiter ? et un flag ?

semop(all->semid, &sem_oper, 1);
pthread_exit(NULL);


Pourquoi n'utilises-tu pas l'interface POSIX ?

sem_init()
sem_wait()
sem_post()
sem_destroy()

l'interface System V est un peu obsolète ...

--
DINH V. Hoa,

"dans la famille, on est tous intelligents" -- sunZ

Avatar
Encolpe DEGOUTE
Dans fr.comp.os.unix, TigrouMeow écrivit:

expose un code minimaliste.



Alors une petite partie d'initialisation :

union semun uVal;

all->semid = semget(all->key, 1, 0006 | IPC_CREAT);
uVal.val = 1;
semctl(all->semid, 0, SETVAL, uVal);

Ensuite je lançe chacun de mes threads... la fonction des threads est celle
ci :

int res;
struct sembuf sem_oper;

sem_oper.sem_num == 0;


sem_oper.sem_num = 0;

Sinon je ne vois pas grand chose à part que la stracture all m'est un
peu absconce.

--
Encolpe DEGOUTE
http://colpi.info
Logiciels libres, hockey sur glace et autres activités cérébrales


Avatar
TigrouMeow
DINH Viêt Hoà wrote:


union semun uVal;

all->semid = semget(all->key, 1, 0006 | IPC_CREAT);


à quoi correspond 0006 ?


Ce sont les droits... même fonctionnement que pour du chmod.. généralement
dans les exemples on trouve 0666 ici, mais 0006 me suffit.

uVal.val = 1;
semctl(all->semid, 0, SETVAL, uVal);

Ensuite je lançe chacun de mes threads... la fonction des threads est
celle ci :

int res;
struct sembuf sem_oper;

sem_oper.sem_num == 0;


test d'égalité ou autre ?


Je suis désolé... j'ai cet erreur depuis le début et j'ai pas été capable de
la voir... je cours me cacher derrière le buisson le plus proche !

Pourquoi n'utilises-tu pas l'interface POSIX ?

sem_init()
sem_wait()
sem_post()
sem_destroy()

l'interface System V est un peu obsolète ...


J'ai vu qu'il y avait des fonctions plus simples pour ça, en effet, mais à
priori JE DOIS utiliser les autres... car c'est un projet pour mes études
(
Par contre j'ai un peu regardé ces fonctions, ils ne me semblent pas
qu'elles donnent autant de liberté que celles que j'utilise ! A priori, ce
sont des "raccourcis" plus simple à utiliser, non ?

En tout cas merci, j'ai trouvé mon erreur grâce à toi... et quel erreur...
je vais pas m'en remettre !


Avatar
DINH Viêt Hoà

DINH Viêt Hoà wrote:


union semun uVal;

all->semid = semget(all->key, 1, 0006 | IPC_CREAT);


à quoi correspond 0006 ?


Ce sont les droits... même fonctionnement que pour du chmod.. généralement
dans les exemples on trouve 0666 ici, mais 0006 me suffit.


Ne voulais-tu pas plutôt 0600 (autorisation uniquement pour ton
utilisateur) plutôt que 0006 (autorisation pour le reste du monde).

J'ai vu qu'il y avait des fonctions plus simples pour ça, en effet, mais à
priori JE DOIS utiliser les autres... car c'est un projet pour mes études
(
Par contre j'ai un peu regardé ces fonctions, ils ne me semblent pas
qu'elles donnent autant de liberté que celles que j'utilise ! A priori, ce
sont des "raccourcis" plus simple à utiliser, non ?


Il y a effectivement une interface plus explicite sur ce que tu veux
faire. Elles peuvent être effectivement implémentées au-dessus de
l'interface System V mais je ne pense pas que cela soit le cas.

--
DINH V. Hoa,

"dans la famille, on est tous intelligents" -- sunZ



Avatar
TigrouMeow
DINH Viêt Hoà wrote:


DINH Viêt Hoà wrote:


union semun uVal;

all->semid = semget(all->key, 1, 0006 | IPC_CREAT);


à quoi correspond 0006 ?


Ce sont les droits... même fonctionnement que pour du chmod..
généralement dans les exemples on trouve 0666 ici, mais 0006 me suffit.


Ne voulais-tu pas plutôt 0600 (autorisation uniquement pour ton
utilisateur) plutôt que 0006 (autorisation pour le reste du monde).


Ce jour là, décidément j'étais fatigué ;) Oui oui bien sur, j'avais corrigé
l'erreur :)

J'ai vu qu'il y avait des fonctions plus simples pour ça, en effet, mais
à priori JE DOIS utiliser les autres... car c'est un projet pour mes
études (
Par contre j'ai un peu regardé ces fonctions, ils ne me semblent pas
qu'elles donnent autant de liberté que celles que j'utilise ! A priori,
ce sont des "raccourcis" plus simple à utiliser, non ?


Il y a effectivement une interface plus explicite sur ce que tu veux
faire. Elles peuvent être effectivement implémentées au-dessus de
l'interface System V mais je ne pense pas que cela soit le cas.


Merci pour tes réponses en tout cas :)