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 } |
Mateusz Mazurek