Hallo,
ich weiß sehr wohl dass ihr mir direkt nur weiterhelfen könnt wenn ihr
den Code seht.
Ich hoffe ihr könnt mir bei meiner Frage auch so weiterhelfen,
da es mehr um ein eingekreister Fehler geht.
Ich habe ein Programm,
dass mehrere Threads nutzt.
Von diesen Threads kann eine Funktion aufgerufen werden die über die
serielle Schnittstelle Sachen versendet: SendCommand
Ich hab diese mit Mutex abgesichert und so weiter. Funktioniert im
Dauerbetrieb, 24h prima.
Damit das Programm dauernd läuft hab ich in der Main() eine
Endlosschleife.
Die hat bisher nichts gemacht.
Jetzt fangen die Probleme an:
1
main(){
2
/* Initialisierung, Threadstarts */
3
while(1){
4
SendCommand(TEMP_SENS_ADDR1,GET_TEMP,0x01);
5
usleep(5000000);
6
}
7
return1;
8
}
Stecke ich in die Endlosschleife der Main() Funktion eine regelmäßigen
Aufruf auf SendCommand, dann hängt irgendwann, nicht von Anfang an,
tcdrain() in einer Endlosschleife und damit alles was auf Sendcommand
beruht. Der Rest läuft weiterhin.
Jetzt meine Frage:
Was kann tcdrain in eine Endlosschleife bringen? Wo, und wie kann die
Fehlersuche am besten machen?
Gruß Daniel
Hallo Daniel,
du schreibst nicht, wie fit du mit Threads bist und welche libc das ist.
Man muss für Multithreading ein Präprozessormakro beim compilieren
setzen und kann nicht jede Libraryfunktion verwenden. Such mal in diesem
PDF nach "thread".
http://www.gnu.org/software/libc/manual/pdf/libc.pdf
Gibt es Signalhandler? Da wird Locking zum Problem.
gruss
Damian
Hi,
bist Du Dir sicher, dass Du tcdrain überhaupt benutzen kannst?
..."The fildes argument is an open file descriptor associated with a
terminal. "
Ist das bei Dir der Fall? So wie ich das sehe, willst Du nur warten, bis
write() fertig ist. Wenn Du synchron schreibst, dann ist das doch
sowieso der Fall. Ich habe jedenfalls schon jede Menge serielle
Kommunikation unter Linux gemacht, aber tcdrain war noch nie dabei...
Gruß, Oliver
danke euch zwei.
Ich muss zugeben ich bin in threads nicht sehr bewandert, da ich aus der
Hardware-Ecke komme. Ja es gibt Signalhandler, ich werde mal
mit euren Stichwörtern weitersuchen.
"fildes" ist bei mir ein geöffneter serieller Port.
Tcdrain() weglassen ist aber auch nicht die Lösung, da ja
irgendwas von mir programmiertes ja schon vorher im argen liegt,
es fällt halt hier auf.
Später kann ich es (wenn besser) auch weglassen :)
Danke!
Daniel
Achso, und ich nutze die Ubuntu/Eclipse/GCC Entwicklungsumgebung von
atmel für den AVR32, Plattform NGW100.
Ich verlinke statisch um keine Probleme zu bekommen, das Filesystem
liegt auf SD-Karte, hat also genug freien Platz, es wird
aber im Filesystem auch nicht viel geschrieben.
Sry hatte ich ganz vergessen!
ok, ich hab das Problem weiter eingekreist:
es scheint am Signal-Handling zu liegen.
Momentan hab ich zwei Funktionen, die auf SendCommand
zugreifen können:
- einmal ein Thread (Thread1), der über eine Funktion weckeThread
mit pthread_cond geweckt wird (es wird auch über mutex gelock, wie
es immer in Beispielcodes zu finden ist)
- einmal direkt aus der Endlosschleife in der main
Die Funktion weckeThread ist mit sigaction
dem SIGNAL SIG_USR1 zugewießen.
Kann das Probleme geben?
Ich weiß einfach nicht mehr weiter, ich würde das
Problem gerne verstehen, nicht nur irgendwie umprogrammieren.
In Kürze:
- periodisch:
Main()(endlos): wacht auf -> sendCommand()
- nicht-periodisch
SIG_USR1: weckeThread()->thread_condition
Thread1(endlos): wartet auf thread_condition -> sendCommand()
Gruß daniel
Hallo Daniel,
ein Thread, der auf einen Mutex wartet, kann von einem Signalhandler
unterbrochen werden. Wenn du nun den selben Mutex im Signalhandler noch
einmal lockst, fängt das Ganze an zu hängen, weil der selbe Thread
praktisch 2 mal auf die Freigabe des Mutex wartet.
Lösung: Alle Signale am Anfang blocken und einen weiteren Thread
aufmachen, den du dann mit sigwait() warten und die Arbeit des
Signalhandlers machen lässt. Dort kann dann wieder fleissig auf den
Mutex zugegriffen werden. Da der Thread ja aktiv mit sigwait() wartet,
kann er auch nicht von einem Signal unterbrochen werden, was ja
anscheinend die Ursache für dein Problem ist.
Da Threads auch nicht so mein täglich Brot sind, schau mal dort bim
Unterpunkt Signalhandler rein:
http://www.linuxjournal.com/article/2121
ist zwar schon ziemlich alt, aber das Meiste trifft immernoch zu.
gruss Damian