Frage

Ich bin ein mehrere Erzeuger / Verbraucher-Problem in C versucht, aber es ist nicht wie erwartet funktioniert. Hier finden Sie einige Pseudo-Code meine Implementierung darzustellen.

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);
}

Doch mit dieser Lösung data1 füllt sich, aber thread2 verriegelt und nie ausgeführt. Gibt es etwas falsch mit meiner Implementierung?

EDIT # 1

Eines der Probleme, ich fand, war, dass meine zweite Mutex nicht korrekt erstellt werden. Ich weiß nicht, was mit ihm los ist, damit ich für alle Threads die erste Mutex nur bin mit. Es gibt auch etwas, was ich getan habe, um es arbeiten, also werde ich mein Pseudo-Code aktualisieren diese später zu reflektieren, wenn ich eine Minute.

War es hilfreich?

Lösung

Stellen Sie sicher, dass Sie schreiben data1_empty und data2_empty zunächst.

Andere Tipps

Wenn Sie irgendeine Art von Nutzungsart für Data Warteschlangen, sollten Sie in der Lage sein, die „leer“ Semaphore vollständig zu entfernen, es sei denn, Sie versuchen, die Bedingung zu verhängen, dass jede Data Warteschlangentiefe streng 0 oder 1. Wenn Sie eine lokale Variable in thread2, können Sie die Größe des kritischen Abschnitts reduzieren.

Der Code wird dann so etwas wie folgt aus:

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
}

Was wringt-wringen sagte, und nicht versuchen, die Sperre für data_1 zu halten, während Sie für data_2_empty auf jemand warten. Sie können dies erreichen, indem einen alternativen Puffer für data_1 halten und data_2, die Sie tauschen. Thread_2 Swaps DATA_1, während es in data_2 Verarbeitung thread_3 data_2 auslagert, während es verarbeitet wird. Ihre aktuellen Pseudo-Code ermöglicht Thread 1 und Thread 3 gleichzeitig ausgeführt werden, aber es wird nicht zulassen, dass Gewinde 2 zur gleichen Zeit wie die beiden anderen auszuführen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top