Hlavní navigace

Názor ke článku Temná strana linuxu - spouštění procesů od Ondřej Novák - @11 No to jsem právě zkoušel, protože jsem...

  • 23. 1. 2012 10:40

    Ondřej Novák (neregistrovaný)

    @11 No to jsem právě zkoušel, protože jsem psal i implementaci té třídy pro Windows. Je to tak, že pokud na HANDLE povolím "inherit", pak spuštěný proces neobdrží duplikáty těch handlů, ale přímo ty handly. Budou mít stejná čísla a opravdu, pakliže některá stran ten HANDLE uzavře, zavře se na obou stranách. Nejde tedy o duplikát, kde se vede čítač referenci, jde skutečně o sdílení, nebo dědění handlů

    Tohle mi nadělalo docela komplikace. Pokud píšu komunikaci tak, že pustím process, nasypu do něj data a následně si přečtu výsledek až do EOFu, tedy na linuxu do stavu broken pipe... protože process skončil a svou stranu zavřel, ... tak na Windows se nikdy EOFu nedočkám. Protože skončený process nevlastnil duplikát, ale nasdílený HANDLE z parent procesu. Není možné, že bych tam měl chybu, protože to bylo první co mi to udělalo, zůstalo to na čtení v deadlocku. Napadlo mě tedy po spuštění process HANDLE pro druhou stranu u sebe zavřít a na druhé straně na mě vyskočila hláška "Neplatný popisovač". Tím jsem objevil to, že jde skutečně o sdílení HANDLŮ, nikoliv vytváření duplikátů.

    Tyhle potíže vedou k tomu, že v mé knihovně mám několik specialit. Jednou z nich je, že otevření standardního IO se provádí vždycky duplikováním toho, co je vraceno přes GetStdHandle(), tak, aby to pak ta třída mohla bezpečně zavřít přes CloseHandle (a nezavřela si přitom konzoli celou). Na straně parenta je doporučení, že roury sdílené do druhého procesu je nutné zavírat až v okamžiku, kdy parent má jistotu, že si child všechny roury zduplikoval. U standardních I/O to řeším tak, že čtení z roury dělám přes třídu, která EOF kontroluje nejen přes uzavření roury druhou stranou, ale má k dispozici i handle procesu, který souběžně kontroluje. A pokud při čekání na data dojde k ukončení processu, vrátí do aplikace EOF. Je tam použit asynchroní roura přes OVERLAPPED a při čekání na data se čeká pomocí WaitForMultiple­Objects.

    On v tom Linux není sám, na Windows najdeme zase jiný extrabuřty