[Qt] QMutex unlock: wakeOne?

Fórumok

Sziasztok!

Mintha olvastam volna valahol, de mar nem vagyok benne biztos, azota meg nem is talalom.

Szoval a kerdesem: QMutex eseteben ugye az egyes threadek blokkolodnak, ha a QMutex mar eleve lockolt, egeszen addig, ameddig meg nem hivodik ra az unlock. Mi a helyzet ha tobben is varnak ugyanarra a mutexre? Az unlock utan automatikusan egy wakeOne hivodik meg, vagy wakeAll?

Nem latom sehol leirva, es most nem is tudom tesztelni.

Ha valaki tudja a valaszt es megosztana, megkoszonnem.

greenvirag

Hozzászólások

unlock() után ugyanaz a helyzet, mint amikor először értek a szálak a lock()-hoz. Csak az egyik fog továbbmenni, és lock-olja a mutexet. Hogy ez melyik szál lesz, azt szerintem nem lehet előre tudni, mert az os ütemezésén múlik.

Hat ha nem is igy hivjuk, azert a hatterben, voltakepp megis errol van szo.

A thread sleep-be kerul, amig a a mutex lockolva van. Amint a lockolas feloldodik, a thread felebred, es folytatja dolgat, azaz megkaparintja a mutexet, lockolja maganak, es teszi amit tennie kell.

Persze hivatalosan wakeOne, wakeAll tenyleg waitconditionnel van, de ha a szo szerinti jelenteset nezem, megiscsak threadek felebredeserol van szo, nem? Bar igazabol annyi a kerdes, hogy gyakorlatilag egy blokkolva varakozas tekintheto-e jelen esetben sleepnek.

Szoval elnezest, ha felreerthetoen fogalmaztam, de szerintem meg pont igy volt logikus megfogalmazni a kerdest. :)

Inkább fordítva van ez, mert a WaitCondition mutex-ekkel van implementálva...

A lényeg az, hogy a mutex olyan mint a budiajtó. Ha valaki bemegy és lockolja, akkor a többiek kint állnak. Ha az első végez, unlockool, kijön, és a kintiek közül az megy be elsőnek, aki a legszemfülesebb. De mindig csak egyvalaki... :)

Egyébként a QMutex Detailed description részében írva is vagyon...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Igen, threadek felébredéséről van szó, de nagyon nem mindegy, hogy miért mentek el aludni azok a threadek.

A mutex unlockolása azon szálak közül ébreszt fel egyet, akik arra vártak, hogy azt a mutexet lockolhassák. A wakeOne()/wakeAll() ezeket a threadeket egyáltalán nem érinti.

A wakeOne()/wakeAll() csak azokat a threadeket érinti, amelyek ezen metódusok meghívásakor erre a waitcondition-re vártak. De a nevükkel ellentétben ők se ébresztenek fel senkit, hanem csak beraknak ezen szálak közül egyet (wakeOne()) ill. berakják az összes ilyen szálat (wakeAll()) azon mutexek várakozási sorába, amelyikkel ők annak idején a wait()-et meghívták. Egy ilyen thread majd akkor fog ténylegesen felébredni, amikor ezt a mutexet megkaparintja.