Question

J'essaie de résoudre un problème de producteurs / consommateurs multiple en C, mais cela ne fonctionne pas comme prévu. Voici un pseudo-code pour représenter mon implémentation.

Thread thread1;
Thread thread2;
Thread thread3;

Data data1;
Mutex data1_mutex;
Semaphore data1_empty;
Semaphore data1_fill;

Data data2;
Mutex data2_mutex;
Semaphore data2_empty;
Semaphore data2_fill;

thread1()
{
   // creates data and places it into data1.

   wait(data1_empty);
   lock(data1_mutex);

   // critical section

   unlock(data1_mutex);
   post(data1_fill);
}

thread2()
{
   // Removes data from data1, processes it, and places it into data2.

   // data1
   wait(data1_fill);
   lock(data1_mutex);

   // data2
   wait(data2_empty);
   lock(data2_mutex);

   // critical section

   // data2
   unlock(data2_mutex);
   post(data2_fill);

   // data1
   unlock(data1_mutex);
   post(data1_empty);
}

thread3()
{
   // Removes data from data2, prints its results, and removes it.

   wait(data2_fill);
   lock(data2_mutex);

   // critical section

   unlock(data2_mutex);
   post(data2_empty);
}

Cependant, avec cette solution, data1 sera saturé, mais thread2 sera verrouillé et ne fonctionnera jamais. Quelque chose ne va pas dans ma mise en œuvre?

EDIT # 1

L'un des problèmes que j'ai constatés est que mon deuxième mutex n'a pas été créé correctement. Je ne sais pas ce qui ne va pas, alors j'utilise simplement le premier mutex pour tous les threads. Il y a aussi quelque chose que j'ai fait pour le faire fonctionner, alors je mettrai à jour mon pseudo-code pour refléter cela plus tard, quand j'aurai une minute.

Était-ce utile?

La solution

Assurez-vous que vous publiez initialement data1_empty et data2_empty .

Autres conseils

Si vous utilisez un type de mise en file d'attente pour Données , vous devriez pouvoir supprimer le symbole "vide". sémaphores complètement, sauf si vous essayez d'imposer la condition que chaque profondeur de file d'attente Data est strictement égale à 0 ou 1. Si vous utilisez une variable locale dans thread2 , vous pouvez réduire le taille de la section critique.

Le code devient alors quelque chose comme ceci:

thread1() {
    //Wait for data to put in the queue (i.e. a blocking socket read)
    lock(data1_mutex);
    data1.push(someData);
    unlock(data1_mutex);
    post(data1_fill);
}

thread2() {
    DataType dataElement;
    wait(data1_fill);
    lock(data1_mutex);
    dataElement = data1.pop();
    unlock(data1_mutex);

    lock(data2_mutex);
    data2.push(dataElement);
    unlock(data2_mutex);
    post(data2_fill);
}

thread3() {
    DataType dataElement;
    wait(data2_fill);
    lock(data2_mutex);
    dataElement = data2.pop();
    unlock(data2_mutex);
    //do something with dataElement here
}

Ce que wrang-wrang a dit et essayez de ne pas verrouiller data_1 pendant que vous attendez data_2_empty. Vous pouvez y parvenir en conservant un tampon alternatif pour data_1 et data_2 que vous permutez. Thread_2 échange data_1 lors du traitement dans data_2, thread_3 substitue data_2 lors du traitement. Votre pseudo-code actuel permettra aux threads 1 et 3 de s'exécuter simultanément, mais il ne permettra pas au thread 2 de s'exécuter en même temps que les autres.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top