Zadanie do wykonania: Stwórz 2 programy. Jeden ma wypełniać wektor liczbami od 0 do 99 w osobnym wątku, drugi, jako proces potomny musi wyświetlić ich kwadrat w osobnym wątku. Tablica musi być przekazana przez plik mapowany w pamięci.
Idźmy od końca. Plik mapowany w pamięci można pomiędzy procesami „przenosić” przez nazwę lub dziedziczyć z procesu-rodzica. Tutaj użyjemy tego 2 sposobu. Wydaje mi się mniej zawody. Na czym polega? Przy tworzeniu pliku mapowanego w pamięci ustawiamy artybuty pozwalające na dziedziczenie. Podobnie postępujemy w przypadku tworzenia procesu. Jeden argument, dokładnie piąty, musi mieć wartość TRUE.
Adres do zmapowanego pliku przekazujemy poprzez argument do procesu potomnego.
Całość opisana jest w komentarzach. Plik który tworzy proces potomny o nazwie hh ;)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | using namespace std; UINT WINAPI Zapelniaj(LPVOID);//funkcja wypelnia wektor HANDLE watekS = CreateEvent(NULL, FALSE, FALSE, NULL); //sygnalizacja zdarzenia HANDLE hFile = NULL, hMapFile = NULL; // zmienne HANDLE - uchwyty int r[100]={0};//wyzerowanie tablicy int main() { HANDLE hWatekG1=NULL; //uchwyt do watku UINT ID_G1=0; // jakies id do watku hWatekG1 = (HANDLE)_beginthreadex(NULL, 0, Zapelniaj, NULL, 0, &ID_G1); //watek zapelnia wektor WaitForSingleObject(watekS,INFINITE);//main czeka na zakonczenie watku FILE* a = fopen("haha.txt", "w");//otwieram plik fwrite(&r, sizeof(int), 200, a); //zapisuje fclose(a);//zamykam hFile = CreateFile("haha.txt", GENERIC_READ|GENERIC_WRITE,0,0, OPEN_ALWAYS,0,0);//tworze plik w jadrze if (hFile == INVALID_HANDLE_VALUE) { //sprawdzenie wystawpienia bledu printf("CreateFile error: %d.\n", GetLastError()); getchar(); return(1);} // struktura zabezpieczen do obiektu mapowanego w pamieci SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; //pozwala dziedziczyc //koniec strukturki char cmd1[30]; //ciag znakow hMapFile=CreateFileMapping (hFile, &sa, PAGE_READWRITE, 0, 0, NULL);//tworze obiekt mapowania sprintf(cmd1, "hh %p", hMapFile);//sklejam napis hh i %p czyli adres hMapFile if(hMapFile==NULL) { printf("CreateFileMapping error: %d\n", GetLastError()); getchar(); return 1; }//sprawdzenie bledu int *pMapFile = (int *)MapViewOfFile (hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);// przydzielam pamiec CopyMemory(pMapFile, r, sizeof(int)*100);//kopiuje tablice wygenerwoana do pamieci STARTUPINFO si = {0}; si.cb = sizeof(STARTUPINFO); PROCESS_INFORMATION pi1; CreateProcess(0, cmd1, 0,0,TRUE, CREATE_NEW_CONSOLE, 0,0, &si, &pi1);//tworze proces. 5 argument powoduje dziedziczenie uchwytu UnmapViewOfFile (pMapFile);//zamykam CloseHandle(hMapFile); cout << "Koniec - Wcisnij Enter"; return 0; } UINT WINAPI Zapelniaj(LPVOID){ for(int i=0;i<100;i++){ r[i]=i; } SetEvent(watekS);//sygnalizuje zakonczenie watku. Dzieki czemu mozna dzialac na //w pelni wypelnionym wektorze } |
No i plik, który będzie odczytywał plik zmapowany w pamięci i wyświetlał kwadraty jego wartości:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | using namespace std; HANDLE watekP = CreateEvent(NULL, FALSE, FALSE, NULL); //zdarzenie UINT WINAPI Odczytaj(LPVOID); //funkcja wyswietlajaca struct PARAM {//struktura parametrow int *t; }; int main(int argc, char *argv[ ]) // Map1bNazwa { HANDLE hMapFile = NULL; sscanf(argv[1], "%p", &hMapFile);//kopiuje adres przekazany jako parametr do hMapFile int *pMapFile = (int *)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0,0, sizeof(int)*100);//wczytuje sobie teraz //obszar pamieci ktory w procesie-rodzicu zapelnilem int* w= new int[100];//tworze nowa tablice CopyMemory(w, pMapFile, sizeof(int)*100); //kopiuje z pamieci do w PARAM a= {w};//ustawiam w jako parametr funkcji UINT ID_G1=0; HANDLE hWatekG1 = (HANDLE)_beginthreadex(NULL, 0, Odczytaj, &a, 0, &ID_G1);//watek wyswietlajacy wektor WaitForSingleObject(watekP, INFINITE);//czekam na zakonczoenie watku tego wyzej UnmapViewOfFile (pMapFile); CloseHandle(hMapFile); puts("Koniec procesu P2"); system("pause"); return 0; } UINT WINAPI Odczytaj(LPVOID p){ PARAM *parm = (PARAM*)p; //odczytuje strukture int* t = parm->t;//pobieram argumtny for(int i=0;i<100;i++){ cout<<t[i]<<"^2="<<pow(t[i],2)<<endl; //wyswietlam kwadrat liczb od 1 do 99 :) } SetEvent(watekP);//sygnalizuje ze zakonczylem } |
Oj daaawnoo mnie tu nie było. Ale wakacje to był czas dużej liczby intensywnych wyjazdów i tak naprawdę, dopiero jakoś… Read More
Cześć! Zapraszam na krótkie podsumowanie kwietnia. Wyjazd do Niemiec A dokładniej pod granicę z Francją. Chrześnica miała pierwszą komunię. Po… Read More
Ostatnio tygodnie były tak bardzo wypełnione, że nie udało mi się napisać nawet krótkiego podsumowanie. Więc dziś zbiorczo podsumuję luty… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W styczniu przeczytałem "Homo Deus: Historia jutra". Książka łudząco podoba do wcześniejszej książki tego… Read More
Cześć! Zapraszam na podsumowanie roku 2023. Książki Zacznijmy od książek. W tym roku cel 35 książek nie został osiągnięty. Niemniej… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W grudniu skończyłem czytać Mein Kampf. Nudna książka. Ciekawsze fragmenty można by było streścić… Read More