Почистване на споделени POSIX обекти при край на процеса / смърт

Има ли някакъв начин да се извърши почистване на споделени обекти за синхронизация на POSIX, особено при срив на процес? Деблокирането на заключени POSIX семафори е най-желаното нещо, но автоматично „събрани“ опашки/област на споделена памет също би било добре. Друго нещо, на което трябва да следите е, че по принцип не можем да използваме манипулатори на сигнали поради SIGKILL, който не може да бъде уловен.

Виждам само една алтернатива: някакъв външен демон, който приема абонаменти и заявки за „keep-alive“, работещ като куче-пазач, така че без да има известия за някакъв обект, той може да затвори/отключи обект в съответствие с регистрираната политика.

Има ли някой по-добра алтернатива/предложение? Никога преди не съм работил сериозно с POSIX споделени обекти (сокетите бяха достатъчни за всичките ми нужди и според мен са много по-полезни) и не намерих приложима статия. С удоволствие бих използвал гнезда тук, но не мога поради исторически причини.


person Roman Nikitchenko    schedule 10.11.2009    source източник


Отговори (3)


Вместо да използвате семафори, можете да използвате заключване на файлове, за да координирате вашите процеси. Голямото предимство на файловите заключвания е, че те се освобождават, ако процесът приключи. Можете да картографирате всеки семафор върху заключване за байт в споделен файл и да знаете, че заключванията ще бъдат освободени при излизане; в повечето версии на unix байтовете, които заключвате, дори не трябва да съществуват. Има код за това в книгата на Marc Rochkind Advanced Unix Programming 1st edition, но не знам дали е в последното 2nd edition.

person Jackson    schedule 11.11.2009
comment
Книгата, която препоръчахте е наистина добра. lockf() обхваща най-малко най-опасната част от първоначалния проблем (застой на семафора)) прототипът, който създадох, работи добре. - person Roman Nikitchenko; 13.11.2009
comment
Между другото lockf() може да се използва с трети параметър, зададен на 0 (целия файл). По този начин не се изисква наличието на истински байт. Поне на Linux. - person Roman Nikitchenko; 13.11.2009

Знам, че този въпрос е стар, но друго чудесно решение са стабилните мутекси на POSIX. Те автоматично отключват и влизат в състояние на „несъвместим флаг“, когато собственикът умре, и следващата нишка, която се опитва да заключи мутекса, получава грешка EOWNERDEAD, но успява да стане новият собственик на мутекса. След това е в състояние да изчисти каквото и да е състояние, което мутексът е защитавал (което може да е в много лошо непоследователно състояние поради асинхронно прекратяване на предишния собственик!) и да маркира мутекса като последователен отново, преди да го отключи.

Вижте документацията за стабилни мутекси тук:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html

person R.. GitHub STOP HELPING ICE    schedule 08.02.2012

Обичайният начин е да работите с обработчици на сигнали. Просто уловете сигналите и извикайте функциите за почистване.

Но вашият демон пазач също има някои предимства. Това със сигурност ще направи системата по-лесна за разбиране и управление. За да стане по-лесно за администриране, вашето приложение трябва да стартира демона, когато не работи и демонът трябва да може да изчисти всички остатъци от последния срив.

person Aaron Digulla    schedule 10.11.2009
comment
Проблемът е, че трябва да останем дори срещу SIGKILL. Коригирах въпроса въз основа на вашия отговор. Какво е свързано с daemon Бих предпочел внедряване на системна услуга, за да мога да проследявам зависимостите. - person Roman Nikitchenko; 10.11.2009
comment
Не трябва да се опитвате да хващате SIGKILL в капан. Ако има грешка във вашия код, би било невъзможно да го прекратите. Значи не искате това. Това, което искате, е да прегледате всички ресурси и да проверите дали все още се използват. Повечето приложения, които използват SHM, предлагат инструмент за почистване на всички споделени ресурси. Предлагам да автоматизирате тази стъпка. - person Aaron Digulla; 10.11.2009
comment
Не просто не трябва - не можете. linux.die.net/man/2/signal Сигналите SIGKILL< /b> и SIGSTOP не могат да бъдат уловени или игнорирани. - person ephemient; 10.11.2009
comment
Съжалявам, смесих това с SIGINT (известен още като Ctrl-C) и SIGTERM (kill команда). - person Aaron Digulla; 10.11.2009
comment
Да, разбирам, че не мога да хвана SIGKILL и SIGSTOP. Току-що отбелязах, че това решение трябва да остане последователно дори ако някой е убил някакъв процес със SIGKILL (например). Въпреки че да, манипулаторите на сигнали трябва да включват освобождаване на споделени ресурси поне в случаите, когато можем да го направим. Ти си прав. - person Roman Nikitchenko; 11.11.2009
comment
Трябва също да освободите ресурсите при стартиране на програмата! Звучи безумно, знам. Причината е, че е възможно принудително да извадите процеса си от системата, преди да имате възможност да почистите. В този случай разпределянето на SHM по време на стартиране ще се провали (тъй като те все още са там). Така че трябва да го направите два пъти: при стартиране първо почистете всичко, след което го разпределете наново. При изключване просто освободите. - person Aaron Digulla; 11.11.2009