Имам една такава странна ситуация, multithreaded приложение, имам няколко нишки (да ги наречем worker-и), които нямат проблем да изпълняват една критична секция паралелно, както и една нишка (да я наречем monitor), която периодично се събужда и върши някаква кратка работа. Термините "worker" и "monitor" са си напълно условни и са лишени от съдържанието, което се влага в тях от академична гледна точка, т.е worker-ите наистина вършат някаква работа, а monitor-а взема някакви хардуерни показатели и на базата на тях влияе на работата на worker-ите.
Докато monitor-а върши тази работа с вземането на хардуерните показатели, останалите няколко нишки не трябва да са в критичната секция. Най-простото решение с мутекс е малоумно, защото не искам да заключвам worker-ите помежду им, това убива производителността най-малкото.
С други думи, няколко worker-а спокойно се изпълняват паралелно. monitor-а трябва да върши работа само когато няма worker-и в критичната секция и докато се изпълнява той, никой worker не трябва да може да влезе там. monitor-а периодично спи една минута, събужда се, прави каквото прави и пак отива да спи и така докато не бъде спрян.
Първите идеи които ми се въртяха в главата бяха комбинации от мутекс и семафор или мутекс и condvar-и. После открих съществуването на rwlock-овете в pthreads и бях просто потресен, цялата концепция идеално ми се вписва и е много проста за ползване.
Оообаче проблем - rwlock имплементацията в линукс е крива и е изключително лесно да докараш monitor-а до starvation, защото се дава приоритет на reader-ите (worker-ите). Worker-ите съответно заключват rwlock-а стотици пъти в секунда и горкия "monitor", който се буди през минута да види състоянието на хардуера, просто не може да вземе ръка
Съвсем буквално, не може да се изпълни изобщо. Не че закъснява, на практика просто не се изпълнява.
Та това поведение може да се промени ако се ползват едни non-portable _np функции, които обръщат поведението и дават приоритет на writer-а (monitor-а). Обаче те са линукс-специфични, което означава че не мога да портна свинщината дори на FBSD.
Та това което ми хрумна е да си поиграя малко с scheduling policy-то на нишките и да вдигна приоритета на monitor нишката. Обаче доколкото чета разни хора дебело предупреждават, че това не е добра идея и може да доведе до доста грозни проблеми, примерно priority inversion такива и така нататък.
Та ако може да си спестя няколко вечери главоблъскане, чудно ми е някой занимавал ли се е точно с този проблем. Дали си струва да се пробвам да променям приоритети и sched policy-та или просто да отеба идеята и да се пробвам да го реализирам с подръчни средства (мутекси и семафори). От една страна тези rwlocks пасват просто тоооооолкова добре на цялата идея и са толкова прости за ползване и така добре лишават от съмнителното щастие да се осереш някъде. От друга страна, portability-то в бъдеще ми е важно. Ебати дилемата...