Domanda

Sto tentando un problema produttore / consumatore multiplo in C, ma non funziona come previsto. Di seguito è riportato uno pseudo codice per rappresentare la mia implementazione.

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

Tuttavia, con questa soluzione i dati 1 si riempiranno, ma thread2 si bloccherà e non verrà mai eseguito. C'è qualcosa di sbagliato nella mia implementazione?

EDIT # 1

Uno dei problemi che ho riscontrato è stato che il mio secondo mutex non veniva creato correttamente. Non so cosa ci sia di sbagliato, quindi sto solo usando il primo mutex per tutti i thread. C'è anche qualcos'altro che ho fatto per farlo funzionare, quindi aggiornerò il mio pseudo-codice per riflettere questo in seguito quando avrò un minuto.

È stato utile?

Soluzione

Assicurati di pubblicare data1_empty e data2_empty inizialmente.

Altri suggerimenti

Se usi una sorta di tipo di accodamento per Dati , dovresti essere in grado di rimuovere il " vuoto " semafori completamente, a meno che tu non stia cercando di imporre la condizione che ogni profondità della coda Data sia rigorosamente 0 o 1. Se usi una variabile locale in thread2 , puoi ridurre la dimensione della sezione critica.

Il codice diventa quindi qualcosa del genere:

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
}

Cosa ha detto wrang-wrang e cerca di non tenere il blocco per data_1 mentre aspetti data_2_empty. È possibile ottenere ciò mantenendo un buffer alternativo per data_1 e data_2 che si scambiano. Thread_2 scambia dati_1 durante l'elaborazione in data_2, thread_3 scambia dati_2 durante l'elaborazione. Il tuo pseudo-codice corrente consentirà l'esecuzione simultanea del thread 1 e del thread 3, ma non consentirà l'esecuzione del thread 2 contemporaneamente a uno degli altri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top