pthread_cond_* en particulier pthread_cond_signal !

Le
Machine
Hello, j'aurais besoin d'un petit coup de main pour placer pthread_cond_sig=
nal dans le code suivant je débute avec les threads et ne pas de solut=
ion

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define MAX 8

struct list {
int i;
struct list *next;
pthread_mutex_t mutex_zone;
pthread_cond_t condition;
};

struct list *init(void) {
struct list *p = malloc(sizeof(struct list));
p->i = 0;
p->next = NULL;
return p;
}

struct list stack = {
.i = 0,
.next = NULL,
.mutex_zone = PTHREAD_MUTEX_INITIALIZER,
.condition = PTHREAD_COND_INITIALIZER
};

void print(struct list *p)
{
printf("%d %p", p->i, p->next);
}

void push(struct list *p)
{
int i = 0;
pthread_mutex_lock(&stack.mutex_zone);
while(i != 1000) {
pthread_cond_wait(&stack.condition, &stack.mutex_zone);
p = &stack;
p->i += 1;
p->next = init();
print(p);
if(i++) {
pthread_cond_signal(&stack.condition);
}
}
pthread_mutex_unlock(&stack.mutex_zone);
}

void pop(/* next time */);

int main(void)
{
struct list *l = init();
pthread_t t[MAX];
int i = 0;
while(i++ < MAX) pthread_create(&t[i], NULL, (void *) push, (void *) l)=
;
for(i = 0; i < MAX; i++) pthread_join(t[i], NULL);
return 0;
}

Cordialement
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Cyprien Nicolas
Le #25688122
Salut,

Le 27/09/2013 13:40, Machine écrivit :
Hello, j'aurais besoin d'un petit coup de main pour placer
pthread_cond_signal dans le code suivant... je débute avec
les threads et ne pas de solution...



Ça ressemble à un TP de programmation parallèle.

Je n'ai pas testé le programme, car je vois une erreur de logique dans
ton main() :

int main(void)
{
struct list *l = init();
pthread_t t[MAX];
int i = 0;
while(i++ < MAX) pthread_create(&t[i], NULL, (void *) push, (void *) l);
for(i = 0; i < MAX; i++) pthread_join(t[i], NULL);
return 0;
}



Ton while (i++ < MAX), t[i]… peut pas être correct, vu que
l'incrément se fait dans le test du while, i vaudra 1 dans le corps de
la boucle, du coup t[0] n'est jamais initialisé.

Soit tu fais un for() comme en-dessous, soit plutôt un do-while avec
préincrément, ou tu déplaces le post-incrément sur la dernière
utilisation du i.

do {
pthread_create(&t[i], NULL, (void *) push, (void *) l);
} while(++i < MAX);

ou alors :

while(i < MAX) pthread_create(&t[i++], NULL, (void *) push, (void *) l);


Mais je trouve cette dernière pas géniale car le ++ est /caché/ dans le
corps de la boucle.

--
Cyp
Machine
Le #25688422
Le vendredi 27 septembre 2013 15:49:56 UTC+2, Cyprien Nicolas a écrit :

Sans vouloir faire d'histoire, l'objet du post est d'abord la fonction push et en particulier les fonctions pthreads_cond_*... en testant le code vous auriez compris que do/while ou for(;;) ne le debug pas...
Cyprien Nicolas
Le #25688502
Le 27/09/2013 19:00, Machine écrivit :
Le vendredi 27 septembre 2013 15:49:56 UTC+2, Cyprien Nicolas a
écrit :

Sans vouloir faire d'histoire, l'objet du post est d'abord la
fonction push et en particulier les fonctions pthreads_cond_*... en
testant le code vous auriez compris que do/while ou for(;;) ne le
debug pas...



Ah ben après coup j'ai testé, et ça segfault dans le for(), donc si, il
y a bien un problème à cet endroit là.

Le reste du programme dans le push me semble correct, l'objet du post ne
mentionnait pas pourquoi ça marche pas, en décrivant le comportement
attendu, et le comportement constaté, il m'est difficile d'aider plus avant.

PS: vos lignes sont un peu longues…

--
« Ceci n'est pas une signature. » — René Magritte (Apocryphe)
Lucas Levrel
Le #25688492
Le 27 septembre 2013, Machine a écrit :

Hello, j'aurais besoin d'un petit coup de main pour placer
pthread_cond_signal dans le code suivant... je débute avec les threads
et ne pas de solution...



Normalement un cond_wait est dans un while(!macondition). Renseigne-toi
sur les « spurious wakeups ».

--
LL
Machine
Le #25688482
Chez moi:

int main(void)
51 {
52 struct list *l = init();
53 pthread_t t[MAX];
54 int i = 0;
55 /* while(i++ < MAX) pthread_create(&t[i], NULL, (void *) push, (void *) l); */
56 do {
57 pthread_create(&t[i], NULL, (void *) push, (void *) l);
58 } while(++i < MAX);
59
60 for(i = 0; i < MAX; i++) pthread_join(t[i], NULL);
61 return 0;
62 }
63

n'arrange rien...
Richard Delorme
Le #25695242
Le 27/09/2013 13:40, Machine a écrit :
void push(struct list *p)
{
int i = 0;
pthread_mutex_lock(&stack.mutex_zone);
while(i != 1000) {
pthread_cond_wait(&stack.condition, &stack.mutex_zone);



le programme bloque ici... le reste n'ai jamais exécuté

p = &stack;
p->i += 1;
p->next = init();
print(p);
if(i++) {
pthread_cond_signal(&stack.condition);



le signal doit être envoyé depuis un autre thread.

}
}
pthread_mutex_unlock(&stack.mutex_zone);
}



Voici un exemple qui marche :

/* j'ai un pool de tâche qui someillent et que je réveille à la demande */

/* une boucle infini ou sommeille une tâche (task) */
void* task_loop(void *param)
{
Task *task = (Task*) param;

lock(task->mutex);
task->loop = true;

while (task->loop) {
if (!task->run) {
condition_wait(task->cond);
}
if (task->run) {
task_search(task);
task_stack_put_idle_task(task->container, task);
}
}

unlock(task->mutex);

return NULL;
}


/* dans un autre thread, l'action qui réveille la tâche */
if ((task = task_stack_get_idle_task(tasks)) != NULL) {
task_init(task);

lock(task->mutex);
task->run = true;
condition_signal(task->cond);
unlock(task->mutex);
}


les lock/unlock/condition_wait et condition_signal sont des macros qui
lancent les fonctions pthread ou leur équivalent windows selon l'OS ou
la bibliothèque utilisée.

--
Richard
Publicité
Poster une réponse
Anonyme