Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: vyvojar 11. 12. 2017, 19:35:15
-
Toto je pro opravdové borce, teď se ukažte :)
Dokázal by někdo říct, proč ta implementace používá 2 mutexy? Wait condition se vždycky používá s mutexem, to jo, ale proč se tady používají 2? Jeden ten "klasický", co jen a vstupu a pak jeden ještě interně. Jediné, co mě napadá, jak na to koukám, že to možná umožňuje
ten wait condition používat i s různými mutexy na vstupu?
https://github.com/qt/qtbase/blob/5.10/src/corelib/thread/qwaitcondition.h
https://github.com/qt/qtbase/blob/5.10/src/corelib/thread/qwaitcondition_unix.cpp
-
Myslíte ten mutex uvnitř té implementace condition variable? Používá se na synchronizaci přístupu k položkám dané c.v. (na rozdíl od mutexu, který předáváte při wait a který slouží k zajištění atomického testování podmínky pro čekání spolu s případným zahájením toho čekání).
-
Toto je pro opravdové borce, teď se ukažte :)
Dokázal by někdo říct, proč ta implementace používá 2 mutexy? Wait condition se vždycky používá s mutexem, to jo, ale proč se tady používají 2? Jeden ten "klasický", co jen a vstupu a pak jeden ještě interně. Jediné, co mě napadá, jak na to koukám, že to možná umožňuje
ten wait condition používat i s různými mutexy na vstupu?
https://github.com/qt/qtbase/blob/5.10/src/corelib/thread/qwaitcondition.h
https://github.com/qt/qtbase/blob/5.10/src/corelib/thread/qwaitcondition_unix.cpp
Já jsem na tohle teda Pepa z Horní Dolní, ale v prvním uváděném odkazu vidím pouze jeden mutex. Sice je tam napsaný dvakrát, ale jednou je napsaný v bloku #ifndef
a jednou v bloku #else
. Ale jak říkám, jsem na to Pepa z Horní Dolní a upřímně - ani pořádně nevím, co je to mutex (něco zběžně).
-
Myslíte ten mutex uvnitř té implementace condition variable? Používá se na synchronizaci přístupu k položkám dané c.v. (na rozdíl od mutexu, který předáváte při wait a který slouží k zajištění atomického testování podmínky pro čekání spolu s případným zahájením toho čekání).
A k čemu je potřeba synchronizovat tím dalším mutexem přístup k datovým členům, když to už by mělo být zajištěno tím mutexem, co vstupuje, protože při volání libovolné metody by měl být locknutý, ne?
-
A k čemu je potřeba synchronizovat tím dalším mutexem přístup k datovým členům, když to už by mělo být zajištěno tím mutexem, co vstupuje, protože při volání libovolné metody by měl být locknutý, ne?
Při provádění operace signal/notify váš mutex (ten, který předáváte do wait) zamykat nemusíte. Musí být zaměčený pouze při volání wait, jinak si jej můžete zamykat a odemykat, jak chcete (aniž byste pracoval s c.v.).
-
Vidim tam jeden mutex v implementaci QWaitConditionPrivate (https://github.com/qt/qtbase/blob/5.10/src/corelib/thread/qwaitcondition_unix.cpp#L117).
A tu samotnou tam vidim instancovanou take jen jednou v implementaci konstruktoru QWaitCondition() (https://github.com/qt/qtbase/blob/5.10/src/corelib/thread/qwaitcondition_unix.cpp#L170).
-
A k čemu je potřeba synchronizovat tím dalším mutexem přístup k datovým členům, když to už by mělo být zajištěno tím mutexem, co vstupuje, protože při volání libovolné metody by měl být locknutý, ne?
Při provádění operace signal/notify váš mutex (ten, který předáváte do wait) zamykat nemusíte. Musí být zaměčený pouze při volání wait, jinak si jej můžete zamykat a odemykat, jak chcete (aniž byste pracoval s c.v.).
Máte pravdu, i když je asi běžnou praxí, že se ten mutex zamýká i před notify, tak to tak být nemusí. Díky :)
-
A k čemu je potřeba synchronizovat tím dalším mutexem přístup k datovým členům, když to už by mělo být zajištěno tím mutexem, co vstupuje, protože při volání libovolné metody by měl být locknutý, ne?
Napadají mě tři důvody:
- Implementace interně používá pthread_mutex_t, ale interface nabízí volání wait s QMutex nebo QReadWriteLock
- Autorovi kódu připadalo lepší/bezpečnější zařídit si zamykání interně, než se spoléhat na externě dodaný zamčený zámek.
- Metody wakeOne() a wakeAll() nevyžadují volání se zamčeným zámkem (i když takové volání většinou není dobrý nápad). Navíc je takto kód připravený na případné přidání dalších (např. ladicích) metod, které zafungují i bez externího zámku.
-
Ono je to prosté, milý Watsone. Musíš rozlišovat public interface a privátní implementaci.
Tohle: https://github.com/qt/qtbase/blob/5.10/src/corelib/thread/qwaitcondition.h#L62 je public interface a dostává to QMutex.
Tohle: https://github.com/qt/qtbase/blob/5.10/src/corelib/thread/qwaitcondition_unix.cpp#L117 je privátní implementace a používá to pthread mutex.
Jsou to úplně jiné datové typy. Na unixu je v privátní implementaci pthread mutex, na Windows tam může být nějaký WINAPI mutex nebo cokoliv jiného. Přitom nemusí platit, že implementace QMutexu odpovídá privátní implementaci mutexu v qwaitcondition.
V privátní imlementaci je metoda, která opravu čeká: https://github.com/qt/qtbase/blob/5.10/src/corelib/thread/qwaitcondition_unix.cpp#L136, ta musí používat ten privátní mutex, nelze do toho dát QMutex, o kterém vůbec nevíš, jak je interně implementovaný. Teoreticky, kdyby i QMutex interně využíval pthread mutex, dal by se použít a privátní mutex by tam nemusel být, ale byla by to architektonická prasárna.