C++ a vnitřní svět David Bednárek Jakub Yaghob Filip Zavoral
Vazby na OS Co není řešeno ISO normou Pokročilá práce se soubory Paměťově mapované soubory, asynchronní soubory Práce s adresáři Práce s procesy a vlákny Synchronizační primitiva Sdílená paměť DLL Jednotné rozhraní, implementace podle OS
Asynchronní soubory Spuštění souborové operace a pokračování v práci Vznik nové entity, na které se dá zjistit stav operace nebo čekat na dokončení operace Aplikace async_read OS start read is_ready read finished
Asynchronní soubory demo Windows HANDLE f = CreateFile( f.txt, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS FILE_FLAG_OVERLAPPED, 0); OVERLAPPED o; memset(&o, 0, sizeof(overlapped)); o.hevent = CreateEvent(0, TRUE, FALSE, 0); o.offset = offs; ReadFile(f, buf, sz, &rsz, &o); WaitForSingleObject(o.hEvent, INFINITE); CloseHandle(o.hEvent); CloseHandle(f); AIO int f = open( f.txt, O_RDONLY O_LARGEFILE, rights); aiocb a; memset(&a, 0, sizeof(aiocb)); aiocb. aio_fildes = f; aiocb. aio_offset = offs; aiocb. aio_nbytes = sz; aiocb. aio_buf = buf; aiocb. aio_sigevent.sigev_notify = SIGEV_NONE; aio_read(&a); aio_suspend(&a, 1, 0); rsz = aio_return(&a); close(f);
Paměťově mapované soubory Namapování, odmapování souboru Na otevřený soubor Vytvoření, zánik okna Soubor VAP okno
Paměťově mapované soubory Windows
Paměťově mapované soubory demo Windows HANDLE f = CreateFile( f.txt, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0); HANDLE m = CreateFileMapping(f, 0, PAGE_READONLY, 0, sz, 0); void *p = MapViewOfFileEx(m, FILE_MAP_READ, 0, offs, sz, hinta); POSIX int f = open( f.txt, O_RDONLY O_LARGEFILE, rights); void *p = mmap(hinta, sz, PROT_READ, MAP_SHARED, f, offs); munmap(p, sz); close(f); UnmapViewOfFile(p); CloseHandle(m); CloseHandle(f);
Práce s adresáři Otevření, zavření adresáře U některých OS i s filtrem jmen Čtení adresáře Získání jména, atributů, velikosti, práv, Vytváření, rušení adresáře
Práce s adresáři demo Windows WIN32_FIND_DATA ffd; HANDLE dir = FindFirstFile( C:\\*.*, &ffd); do { // do something with ffd.cfilename and ffd. dwfileattributes } while(findnextfile(dir, &ffd)); FindClose(dir); POSIX DIR *dir = opendir( / ); for(;;) { } dirent *de = readdir(dir); if(!de) break; // the end // do something with de->d_name and de->d_type closedir(dir);
Práce s procesy a vlákny Start nového procesu Předání parametrů, prostředí Start vlákna, čekání na dokončení vlákna Bude řešeno v C++ 0x
Vlákna demo Windows class thr_class { public: void start(); int thr_fnc() = 0; private: static DWORD WINAPI win_thr(lpvoid p); }; DWORD WINAPI thr_class::win_thr(lpvoid p) { } thr_class *tc = static_cast<thr_class*>(p); return tc->thr_fnc(); void thr_class::start() { } DWORD thrid; CreateThread(0, ssz, win_thr, this, 0, &thrid); pthread class thr_class { public: void start(); void thr_fnc() = 0; private: static void *p_thr(void *p); pthread_attr_t pat; }; void *p_thr(void *p) { thr_class *tc = static_cast<thr_class*>(p); tc->thr_fnc(); return 0; } void thr_class::start() { } pthread_attr_init(&pat); pthread_attr_setdetachstate(&pat, PTHREAD_CREATE_DETACHED); pthread_create(&thrid, &pat, p_thr, this);
Synchronizační primitiva Semafory Anonymní, pojmenované Kritická sekce Spin-lock Udělej si sám Atomické (interlocked) operace Windows Events WaitForSingleObject, WaitForMultipleObjects POSIX Pthread
Semafor demo Windows HANDLE s = CreateSemaphore(0, ival, numeric_limits<int>::max(), 0); POSIX sem_t s; sem_init(&s, 1, ival); ReleaseSemaphore(s, 1, 0); sem_post(&s); WaitForSingleObject(s); sem_wait(&s); CloseHandle(s); sem_destroy(&s);
Sdílená paměť Sdílení paměti mezi různými procesy Obvykle identifikována jménem Granularita na stránky MASOS, SASOS offsety VAP A FAP VAP B App B App A App A App B
Sdílená paměť demo SASOS Windows klient HANDLE shm = OpenFileMapping( FILE_MAP_WRITE FILE_MAP_READ, FALSE, moje ); void *p = MapViewOfFileEx(shm, FILE_MAP_READ, 0, 0, sz, hinta); struct s { int n; int *ptr; }; for(int i=0;i<static_cast<s*>(p)->n;++i) cout << static_cast<s*>(p)->ptr[i]; UnmapViewOfFile(p); CloseHandle(shm); Windows server HANDLE shm = CreateFileMapping (INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sz, moje ); void *p = MapViewOfFileEx(shm, FILE_MAP_WRITE, 0, 0, sz, hinta); struct s { int n; int *ptr; }; static_cast<s*>(p)->n = N; static_cast<s*>(p)->ptr = static_cast<char*>(p)+sizeof(s); for(int i=0;i<n;++i) static_cast<s*>(p)->ptr[i] = i; UnmapViewOfFile(p); CloseHandle(shm);
Sdílená paměť demo MASOS Windows klient HANDLE shm = OpenFileMapping( FILE_MAP_WRITE FILE_MAP_READ, FALSE, moje ); void *p = MapViewOfFileEx(shm, FILE_MAP_READ, 0, 0, sz, hinta); struct s { int n; size_t offs; }; for(int i=0;i<static_cast<s*>(p)->n;++i) cout << static_cast<int*>(static_cast<char*>(p) +static_cast<s*>(p)->offs)[i]; UnmapViewOfFile(p); CloseHandle(shm); Windows server HANDLE shm = CreateFileMapping (INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sz, moje ); void *p = MapViewOfFileEx(shm, FILE_MAP_WRITE, 0, 0, sz, hinta); struct s { int n; size_t offs; }; static_cast<s*>(p)->n = N; static_cast<s*>(p)->offs = sizeof(s); for(int i=0;i<n;++i) static_cast<int*>(static_cast<char*>(p) +static_cast<s*>(p)->offs)[i] = i; UnmapViewOfFile(p); CloseHandle(shm);
Sdílená paměť demo POSIX klient int shm = shm_open( moje, O_RDWR, rights); void *p = mmap(hinta, sz, PROT_READ, MAP_SHARED, shm, 0); struct s { int n; int *ptr; }; for(int i=0;i<static_cast<s*>(p)->n;++i) cout << static_cast<s*>(p)->ptr[i]; munmap(p, sz); close(shm); shm_unlink( moje ); POSIX server int shm = shm_open( moje, O_RDWR O_CREAT O_EXCL, rights); void *p = mmap(hinta, sz, PROT_READ PROT_WRITE, MAP_SHARED, shm, 0); struct s { int n; int *ptr; }; static_cast<s*>(p)->n = N; static_cast<s*>(p)->ptr = static_cast<char*>(p)+sizeof(s); for(int i=0;i<n;++i) static_cast<s*>(p)->ptr[i] = i; munmap(p, sz); close(shm); shm_unlink( moje );
DLL Dynamické natažení za běhu Získání adresy funkce podle zveřejněného jména Windows Samostatný EXE vlastní kód, data, heap POSIX Shared objects
DLL demo Windows HANDLE dll = LoadLibrary( moje.dll ); typedef void (*dll_fnc_t)( ); dll_fnc_t dll_fnc = reinterpret_cast<dll_fnc_t> (GetProcAddress(dll, fnc )); dll_fnc( ); FreeLibrary(dll); POSIX void *dll = dlopen( moje.dll, RTLD_NOW); typedef void (*dll_fnc_t)( ); dll_fnc_t dll_fnc = reinterpret_cast<dll_fnc_t> (dlsym(dll, fnc )); dll_fnc( ); dlclose(dll);