#define _POSIX_C_SOURCE 200809L #include /* waitpid */ #include /* close */ #include /* uint64_t */ #include /* memcmp */ #include /* fcntl, F_*, FD_* */ #include /* calloc */ #include #include #include /* Občas je výhodné delší výpočet provádět asynchronně, tzn. tak, * aby zbytek programu mohl během výpočtu normálně pracovat (a * například reagovat na vnější události). Vaším úkolem bude * naprogramovat dvojici podprogramů ‹async_start› a ‹async_wait›, * které realizují takovýto asynchronní výpočet v pomocném procesu. * Pro jednoduchost bude vstupem a výstupem výpočtu jediné 64bitové * číslo. * * Podprogram ‹async_start› obdrží dva parametry: * * • ‹handle› je ukazatel na strukturu ‹async_state›, * • ‹func› je ukazatel na funkci, kterou chceme provést, * • ‹arg› je 64bitové číslo, které bude vstupem pro ‹func›. * * Výsledkem ‹async_start› je identifikátor, který později předáme * podprogramu ‹async_wait› a obdržíme tak výsledek výpočtu. * Podprogram ‹async_wait› zároveň uvolní veškeré zdroje s ‹handle› * spojené. * * Ve struktuře ‹async_state› musí být prostor pro alespoň 16 * souběžných výpočtů. * * Není-li možné vytvořit nový proces (nebo nastane jiná fatální * chyba), výsledkem ‹async_start› bude -1. Výsledkem ‹async_wait› * je v případě úspěchu 0, jinak -1. Výsledek výpočtu je volajícímu * předán výstupním parametrem ‹result›. */ struct async_state { // … max 512 bajtů … }; int async_start( struct async_state *handle, uint64_t ( *func )( uint64_t ), uint64_t arg ); int async_wait( struct async_state *handle, int id, uint64_t *result ); /* ┄┄┄┄┄┄┄ %< ┄┄┄┄┄┄┄┄┄┄ následují testy ┄┄┄┄┄┄┄┄┄┄ %< ┄┄┄┄┄┄┄ */ uint64_t slowpoke( uint64_t val ) { sleep( 5 ); return val * 13; } int main( void ) { struct async_state *handle = calloc( 512, 1 ); assert( handle ); int a_id = async_start( handle, slowpoke, 1 ), b_id = async_start( handle, slowpoke, 2 ), c_id = async_start( handle, slowpoke, 3 ); assert( a_id >= 0 ); assert( b_id >= 0 ); assert( c_id >= 0 ); alarm( 7 ); uint64_t a_res, b_res, c_res; assert( async_wait( handle, a_id, &a_res ) == 0 ); assert( async_wait( handle, b_id, &b_res ) == 0 ); assert( async_wait( handle, c_id, &c_res ) == 0 ); assert( a_res == 13 ); assert( b_res == 26 ); assert( c_res == 39 ); free( handle ); return 0; }