PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : pthread variable läst sich nicht ändern



barton4
04-05-2008, 14:34
Ich will von einer Klasse 2 Objekte erstellen und jeweils eine Funktion run als thread ausführen. Dabei war es notwendig pthread_create den this zeiger für das jeweilig Element mit zu übergeben, dazu hab ich ein wrapper Funktion geschrieben:
(die Wrapperfunktion ist dann ein thread in der die obejct Methode ausgeführt wird )



int Processor::run()
{
cout<<"Processor::run() cpu: "<<endl;
//to start a non static method a special wrapper function is required
//static void *Processor::execute_wrapper_pthreads(void* thisp)
pthread_t thr_0;
pthread_attr_t thr_attr;
pthread_attr_init(&thr_attr);
pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&thr_0, &thr_attr, &Processor::execute_wrapper_pthreads, static_cast<void*>(this));
//---------------------------------------------------
}

void *Processor::execute_wrapper_pthreads(void* thisp)
{
Processor* p_cpu = static_cast<Processor*>(thisp);
p_cpu->stopCPU = true; //scheduler control cpu therfore stop cppu by default
p_cpu->execute();
}


Nun hab ich jetzt 2 threads von 2 unteschiedlichen Objekten(Prozessoren).
Jedes Processorobjekt hat eine bool variable "this->stopCPU" die anzeigt ob der Processor Befehle bearbeiten soll oder leerläufe(idle) ausführt.
Der Prozessor bzw die Methode befindet sich in einer Endlosschleife(in der run methode die vom thread aufgerufen wird) und prüft ob "this->stopCPU"
false ist, wenn es so ist "wacht" er aus dem idle zustand aus. Er fragt also in jedem durchlauf stopCPU ab.

Im "Hauptprogram" bzw. von wo pthread_create aufgerufen wird, werden die Processoren über das bool flag "this->stopCPU" gesteuert (Befehle abarbeiten oder idle)...

das Hauptprogeamm hat einen Zeiger auf das Flag "stopCPU" von jedem Objekt(Prozessor).

wenn ich aber jetzt vom Hauptprogramm "PointerAufObjekt->stopCPU" auf false setzte(bzw den Processor aus den idle status "aufwecken") will passiert nichts.

Die stopCPU Variable in dem jeweiligen thread bleiben gleich, der run Prozess bleibt in der idle schleife.


So sieht die debug Ausgabe aus. Ich hab sie noch etwas kommentiert:


Processor cpu0: 0xfff9cc24 (adresse von stopCPU des Prozessor Objektes)
Processor cpu1: 0xfff9cba4 (adresse von stopCPU des Prozessor Objektes)
Processor::run() cpu: (erste Prozessor thread wird gestarte)
Processor::run() cpu: (2ter Prozessor thread wird gestarte)
scheduler cpu0: 0xfff9cc24 (Addr. von stopCPU für cpu0 vom Hauptprogramm aus )
scheduler cpu1: 0xfff9cba4 (Addr. von stopCPU für cpu1 vom Hauptprogramm aus)
(my cpuid is: 1)
(my cpuid is: 0)
...Ausgabe der einzelnenn cpus

ich lasse vom thread aus und vom Hauptprogramm die Adressen für die Flag Variable ausgebe, wie man sieht zeigen diese auf die gleiche Speicherstelle.


komischerweise bleibt der Prozessor im idle loop und obwohl das Flag im Hauptprogramm auf false gestzt wurde bzw verhält es sich so als ob ich auf unterschiedliche variablen zugreife. Das stopCPU belibt in jedem thread unverändert.

weis jemand was da schief gelaufen ist, muss man bei pthread eventuell noch was beachten??


hänge jetzt schon paar Tage an dieser stelle fest :-(. In endeffekt soll es ein Virtueller Computer werden mit so ne art Pseudo Betriebsystem mit Multitaskting und Multiuser fähigkeiten.

mfg martin

Yonibear
04-05-2008, 15:27
Eventuell denkt der Compiler er kann sich die Prüfung von stopCPU sparen, weil ja innerhalb der Schleife keine Änderung stattfindet. Versuch mal stopCPU mit einem volatile davor zu deklarieren, um den Compiler derartige Optimierungen zu verbieten.

barton4
05-05-2008, 16:54
Danke Yonibear für deine schnelle Hilfe, nach langen überlegen und probieren geht es nun. Aber es lag nicht
an den compilerOptimierungen sondern am Ablauf selber

wärend der thread erst vom wrapper aus aufgerufen wird, wird im Hauptprogramm das stopCPU Flag schon auf false gestellt und der Wrapper stellt es wieder um



void *Processor::execute_wrapper_pthreads(void* thisp)
{
Processor* p_cpu = static_cast<Processor*>(thisp);
p_cpu->stopCPU = true; //!!! das ist die Zeile die mir Tagelang Kopfzerbrechen beschert hat
p_cpu->execute();
}


d.h wenn der Processorthread ausgeführt wird steht stopCPU schon lange wieder auf true (in den meisten fällen).