Ich mache Multithread-Programm mit Pthreads. Die Idee ist einfach:Pthreads - Produzent und Verbraucher mit Zustandsvariable und Mutex - Join Fehler und seltsame Cout
- Car (Gewinde)
- Benzinversorgung (Gewinde)
- Tankstelle (resource)
Beide Auto und Tankstelle etwas Kraftstoff Kapazität haben und nach dem Auto aus Treibstoff muss Tankstelle besuchen. Nachdem die Tankstelle keinen Kraftstoff mehr hat, läuft der Benzinversorgungsfaden und füllt die Ressource nach. Alles scheint gut zu sein, außer dass ich pthread_exit
anstelle von pthread_join
verwenden muss, um auf Threads in der Hauptfunktion zu warten und manchmal doppelt cout
für das gleiche Auto vorkommt: "-----End of fuel-----"
. Mache ich es richtig?
Structs und einige globale Variablen:
#define initialFuel 100
#define loop 10
pthread_mutex_t mutex1, mutex2;
pthread_cond_t isempty;
PetrolDistributor petrolDistributor;
struct Car {
int capacity = 10;
int petrol = 5;
};
struct PetrolDistributor {
int petrol = initialFuel;
bool isEmpty = false;
};
Themen:
void * threadSupply(void *arg)
{
for(int i = 0; i<loop; i++)
{
pthread_mutex_lock(&mutex1);
while(!petrolDistributor.isEmpty)
{
pthread_cond_wait(&isempty, &mutex1); //When signal received, do below:
usleep(2000000);
petrolDistributor.petrol = initialFuel; //Refill petrol and change state
petrolDistributor.isEmpty = false;
}
pthread_mutex_unlock(&mutex1);
}
}
void * threadPetrolDriver(void *arg)
{
Car *car;
car = (Car*) arg;
for(int i = 0; i<loop; i++)
{
while(car->petrol > 0) // Car consumes petrol here
{
usleep(200000);
cout << car->petrol << endl;
car->petrol -= 1;
}
cout << "-----End of fuel-----" << "\t\t #" << i << endl;
pthread_mutex_lock(&mutex1);
if (petrolDistributor.petrol >= 30) // If distributor almost empty?
{
petrolDistributor.petrol -= car->capacity; //Substract car's capacity amount of fuel from distributor
car->petrol = car->capacity; //Fillup mentioned capacity in car
}
else
{
petrolDistributor.isEmpty = true;
pthread_cond_signal(&isempty);
}
pthread_mutex_unlock(&mutex1);
}
}
Main:
int main()
{
pthread_t car;
pthread_t supply;
Car carPetrol;
pthread_cond_init(&isempty, NULL);
pthread_mutex_init(&mutex1, NULL);
pthread_create(&car, NULL, threadPetrolDriver, (void*) (&carPetrol));
pthread_create(&supply, NULL, threadSupply, NULL);
// pthread_join(&car, NULL); //results error: invalid conversion from ‘pthread_t* {aka long unsigned int*}’ to ‘pthread_t {aka long unsigned int}’ [-fpermissive]|
// pthread_join(&supply, NULL);
pthread_exit(NULL);
return 0;
}
Ausgabebeispiel:
-----End of fuel----- #0
9
(...)
2
1
-----End of fuel----- #1
-----End of fuel----- #2 //Also for loop increments
10
9
(...)
3
2
1
-----End of fuel----- #3
10
9
(...)
Und die Frage ist, warum Ausgang nicht so aussieht? Manchmal sind fünf Iterationen in Ordnung und sechs zeigt doppelte Nachricht. Und was ist los mit Join? Danke für Ratschläge.
Es ist ein bisschen komisch, dass Sie sich der Notwendigkeit bewusst sind, Ihren 'pthread_cond_t' zu initialisieren, aber scheinen, Inhalt Ihren' pthread_mutex_t 's-Standard-initialisiert zu halten. Außerdem scheinen Sie 'pthread_cont_t' als Semaphor zu glauben. Es ist nicht. – EOF
Danke für die Antwort und Ihre Anmerkungen, fehlende Mutex-Initialisierung hinzugefügt. Nicht sicher, wie man den zweiten Teil deines Ratschlags benutzt, weil ich andere Stack-Themen untersuchte. Leute haben vorgeschlagen, 'pthread_mutex_t' und' pthread_cont_t' auf diese Weise zu mischen, aber ich könnte falsch liegen. – Macieyo
Hinweis: 1. Parameter von pthread_join() ist eine pthread_id, aber Sie haben eine pthread_t zur Verfügung gestellt. Nicht das Gleiche. (Dies ist keine Antwort, weil es nicht seine (primäre) Frage ist.) –