Threadsichere Queue
-
Hallo,
ich habe unter WINCE ein Applikation die für Daten zwischen den Threads eine Queue benutzt. Soweit so gut da ich den Einbauer sowie Ausbauer über CritikalSection gesichert habe.
Jetzt heisst es aber von meinen Kollegen dass unter WINCE ein CritikalSection quasi zum Deadlock führen kann.
Und zwar:
A=highest Prior, B= MiddlePrior,C=LowPrior, D=LowersPrior Thread
Im C Thread ist der Ausbauer.Wenn A jetzt Einbaut und C gerade bei Ausbauen ist dann bleibt A stehen. Die Frage ist bis wann?
a) Bis C Fertig, aber wie wenn A die höchste Prior hat
b) Und was passiert wenn gerade noch der B einschlägt oder sogar einbauen will.Grund sei angeblich dass die Thread Prior nicht durch Sceduler angehoben wird wenn C durch A ins schlaffen gelegt wurde.
Aus diesen Gründen soll ich meine Queue umbauen aber weiss nicht genau wie.
Alle meine Gedanken mit InterlockIncrement usw. führen nach meine Meineung nach nicht zu Threadsicheren Queue.Weiss jemand ein Rat oder Anworten in bezug auf WinCE?
-
nimm z.b. dies: http://svn.akop.org/psp/tags/fuse/0.9.0.1/sound/sfifo.c
braucht keine locks und kann daher auch nicht 'deadlocken'
-
Nur als Anmerkung: Der Code ist GPL und lässt sich somit nur sehr eingeschränkt (in kommerziellen Anwendungen) nutzen...
-
Jochen Kalmbach schrieb:
Nur als Anmerkung: Der Code ist GPL und lässt sich somit nur sehr eingeschränkt (in kommerziellen Anwendungen) nutzen...
LGPL. ist kommerziell nutzbar, aber der quelltext muss einsehbar sein.
btw, der code taugt was, ich benutze ihn z.b. zur entkopplung der interaktion zwischen RTOS-tasks (untereinander) und zwischen interrupt-routinen. lock-freie systeme sind schon eine feine sache, weil z.b. deadlocks komplett ausgeschlossen sind.
-
Der Code ist aber GPL! Es gilt *immer* die striktere Lizenz! Und da beide erwähnt werden (LGPL & GPL) ist es nun mal GPL...
-
Jochen Kalmbach schrieb:
Der Code ist aber GPL! Es gilt *immer* die striktere Lizenz! Und da beide erwähnt werden (LGPL & GPL) ist es nun mal GPL...
ach stimmt, du hast recht. naja, kommerzielle verwertung ist ja trotzdem erlaubt.
-
Naja... aber nicht wirklich.... da Du ja dann selber den *gesamten Source unter GPL stellen musst... was sich eigentlich ausschliest... es sei Denn Du hast eine OpenSource-Firma...
Aber mir ist das schon lange bewusst: OpenSource ist wunderbar, so lange man sich nicht um die Lizenzen schert...
-
abgesehen von den Lizenzen, das schaut doch aus wie ein Ringbuffer.
/*
* Porting note:
* Reads and writes of a variable of this type in memory
* must be *atomic*! 'int' is *not* atomic on all platforms.
* A safe type should be used, and sfifo should limit the
* maximum buffer size accordingly.
*/typedef int sfifo_atomic_t;
typedef struct sfifo_t
{
char buffer;
int size; / Number of bytes /
sfifo_atomic_t readpos; / Read position /
sfifo_atomic_t writepos; / Write position */
} sfifo_t;das *atomic* bezieht sich jetzt nicht auf den Datenspeicher "buffer"
sondern auf die Lese- und Schreibpositionen !? Oder versteh ich das falsch ?Von atomic Operationen hab ich ja ne Vorstellung, Operationen die ohne
Unterbrechung ausgeführt werden, aber wie ist das in Zusammenhang mit
*this type in memory* zu verstehen#ifdef __TURBOC__
# define SFIFO_MAX_BUFFER_SIZE 0x7fff
#else /* Kludge: Assume 32 bit platform */
# define SFIFO_MAX_BUFFER_SIZE 0x7fffffff
#endifIst damit gemeint, auf 16 bit Plattformen würden mögliche 32bit Werte in 2
Registern gehalten, was dann nicht mehr atomic ist ...Hab ich das richtig oder falsch aufgefasst ?
Danke !
-
@Michael S.:
Ich verstehe nicht wie Dein beschriebenes Szenario zu einem Deadlock führen kann!
-
Hallo,
Ich verstehe es auch nicht. Selbst wenn ein Thread mit höhrere Priorität wartet, beliben die anderen ja nicht stehen.Und bei CriticalSection geht der Thread doch eh in einen Idle-Mode zum warten oder nicht?
Stefan
-
RED-BARON schrieb:
Ist damit gemeint, auf 16 bit Plattformen würden mögliche 32bit Werte in 2
Registern gehalten, was dann nicht mehr atomic ist ...Hab ich das richtig oder falsch aufgefasst ?
Hast du richtig verstanden, ist analog zu 32Bit Systemen und 64Bit Werten.
-
Martin Richter schrieb:
@Michael S.:
Ich verstehe nicht wie Dein beschriebenes Szenario zu einem Deadlock führen kann!Vielleicht meint er das: http://msdn.microsoft.com/en-us/library/aa450594.aspx
-
TheTester schrieb:
Martin Richter schrieb:
@Michael S.:
Ich verstehe nicht wie Dein beschriebenes Szenario zu einem Deadlock führen kann!Vielleicht meint er das: http://msdn.microsoft.com/en-us/library/aa450594.aspx
Und hiew steht doch klar, dass dieses Problem durch den Priority Boost, bzw. Priority Inversion gelöst wird!
Ich verstehe immer noch nicht wie hier ein Deadlock geschehen kann...
-
Erstmal danke für die Antworten:
Ich glaube das soll das Problem sein dass WinCE (Ver.5.0) Priority Boost, bzw. Priority Inversion nicht ausführen wird.
Denn nur dadurch kann der höherpriorisierter Thread wieder fortgesetzt werden.
Zur Erinerung:
Thread A => hochprior. thread
Thread B => niedrigprior. threadThread A:
m_cs.Lock();
RB.Einbau();
m_cs.Unlock();Thread B:
m_cs.Lock();
RB.Ausbau();
m_cs.Unlock();B wird unterbrochen von A in der CriticalSection Ausführung (RB.Ausbau() )
=> A wird warten (und das solange bis B wieder fortgesetzt wird wegen Lock von B). B kann aber nur fortgesetzt werden wenn die Prior. von B >= A wird, was OC machen müsste (Priority Boost). Fehlt der Priority Boost was angeblich unter WinCE nicht gibt wird A nie fortgestezt was zu DeadLock führt. (DeadLock = Thread wird nie fortgesetzt werden können)Das ist nach meinem verständis.
Sehe ich da etwas falsch?
-
Ich glaube das ist die Antwort auf meine eigentliche Frage:
http://msdn.microsoft.com/en-us/library/aa450594.aspx
Danke.