Процессы и потоки

Міністерство освіти і науки України

Житомирський державний технологічний університет





ФІКТ

Кафедра ПЗОТ

Група ПІ-39















Лабораторная робота №8

по курсу

Системное программирование

на тему

Процессы и потоки

















г. Житомир

2011 р.


Задание



Необходимо написать две программы, которые будут иметь общие данные.

Существует несколько механизмов реализации общего доступа к данным разных процессов. Воспользуемся одним из них, наиболее удобным – проецированием файла в память. Одна программа будет сортировать данные в файле, а другая отображать содержимое этого файла. Работать оба процесса будут одновременно.

программа массив процесс

Ход работы



Создайте файл data.dat. В нем записаны числа, сгенерированные случайным образом. Количество чисел – 20-30 штук. Диапазон значений:от 10 до 100. (Это именно числа, а не символьные строки хранящие ASCII коды цифр!!!)

Программа №1. «Сортировка данных»

		Берем за основу программу лаб.раб №4. 

		Включаем обработку события нажатия клавиши, и отслеживаем в нем нажатие пробела. Если пользователь нажал пробел, значит начинаем сортировку данных. 

		Выполняем проецирование файла в память. Используем для этого созданный файл data.dat. В результате получим доступ к данным как к обычному одномерному массиву. 

		Выполняем сортировку массива, любым из методов сортировки. Вставьте 1-но секундную задержку для каждой итерации сортировки массива, это позволит потом наглядней увидеть процесс сортировки. 

		По окончанию сортировки, программа выводит в окно, строку «Работа завершена». 

Программа №1. «Вывод файла данных в окно»

Берем за основу программу лаб.раб №4. 

Выполняем проецирование файла в память. Используем для этого созданный файл data.dat. В результате получим доступ к данным как к обычному одномерному массиву. Этот же файл проецирует в память предыдущая программа. 

Создаем таймер на 0.5 секунды. При получении сообщения от таймера, выполняем вывод всего массива в окно. Предусмотрите корректный перевывод данных в окно, без наложений. В окно выводим не числа из массива, а строки одного и того же символа, например «*», в количестве равном числу из массива.

Запускаем на выполнение обе программы одновременно. Когда вторая программа запустилась и выполняет вывод данных в окно (выводит пока одну и туже картинку каждые пол секунды), нажимаем пробел в первой программе и она начинает сортировать массив. При этом, так как они данные берут из одного и того же файла (обе проецировали его себе в память), то первая вносит изменения переставляя данные при сортировке, а вторая выводит из себе в окно и мы видим ход процесса сортировки. Временную задержку в первой программе можно при надобности увеличить.

Эти две программы демонстрируют возможность организации общего доступа процессов к одним и тем же данным. Так же демонстрируется механизм проецирования файла в память, как один из наилучших методов доступа к файлу.



Код программы



Програма №1



LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;



HANDLE FileMappingHandle, FileHandle, MutexHandle;

HINSTANCE exec;

int* Image;



int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

	static char szAppName[] = "FileImageViewer" ;

HWND hwnd ;

MSG msg ;

WNDCLASSEX wndclass ;



wndclass.cbSize = sizeof (wndclass) ;

wndclass.style = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc = WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

wndclass.hInstance = hInstance ;

wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName = NULL ;

wndclass.lpszClassName = szAppName ;

wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;



RegisterClassEx (&wndclass) ;



hwnd = CreateWindow (szAppName, 

						"FileImageViewer", 

						WS_OVERLAPPEDWINDOW, 

						200, 

						10, 

						CW_USEDEFAULT, 

						CW_USEDEFAULT, 

						NULL, 

						NULL, 

						hInstance, 

						NULL) ;		 



ShowWindow (hwnd, iCmdShow) ;

UpdateWindow (hwnd) ;



while (GetMessage (&msg, NULL, 0, 0))

{

		TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}



LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

	HDC hdc ;

PAINTSTRUCT ps ;

RECT rect ;



switch (iMsg)

{

		int i;

case WM_CREATE:

							FileHandle=CreateFile(".\\..\\mass.dat", GENERIC_WRITE|GENERIC_READ, 

													FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 

													FILE_ATTRIBUTE_NORMAL, NULL);

							if(FileHandle==NULL)

							{

								MessageBox(hwnd, "Невозможно открыть файл", "Ошибка", MB_ICONWARNING);

								exit(1);

							}

							srand((unsigned)time(NULL));

							str="";

							buf.push_back(str);

							int t[26];

							for(i=0; i<26; i++)

							{

								t[i]=rand()%100;

								if(t[i]<10)

									t[i]+=10;

							}

							unsigned long z;

							exec=ShellExecute(hwnd, NULL, ".\\..\\SysLab8_2\\Debug\\SysLab8_2.exe", NULL, 

											".\\SysLab8_2\\Debug\\", SW_SHOWNORMAL);

							SetTimer(hwnd, NULL, 500, NULL);

							WriteFile(FileHandle, t, sizeof(int)*26, &z, NULL);

							FileMappingHandle=CreateFileMapping(FileHandle, NULL, PAGE_READWRITE, 0, 0, "mass");

							if(FileMappingHandle==NULL)

							{

								MessageBox(hwnd, "Ошибка создания дескриптора проэцирования", "Ошибка", MB_ICONWARNING);

								exit(1);

							}

							Image=(int*)MapViewOfFile(FileMappingHandle, FILE_MAP_READ, 0, 0, 0);

							if(Image==NULL)

							{

								MessageBox(hwnd, "Ошибка проэцирования файла", "Ошибка", MB_ICONWARNING);

								exit(1);

							}

							MutexHandle=CreateMutex(0,FALSE, "massmutex");

							if(MutexHandle==NULL)

							{

								MessageBox(hwnd, "Невозможно создать мутекс", "Ошибка", MB_ICONWARNING);

								exit(1);

							}

							return 0 ;



		case WM_PAINT:

							hdc = BeginPaint (hwnd, &ps) ;

							GetClientRect (hwnd, &rect) ;

							for(i=1; (unsigned)i<(unsigned)buf.size(); i++)	

								TextOut(hdc, 10, i*15, buf[i].c_str(), buf[i].length());

							EndPaint (hwnd, &ps) ;

							return 0 ;



		case WM_TIMER:

							__try

							{

								WaitForSingleObject(MutexHandle, INFINITE);

								buf.clear();

								str="";

								buf.push_back(str);

								for(i=1; i<26; i++)	

								{

									for(int j=0; j<*(Image+i); j++)

										str+="*";

									buf.push_back(str);

									str="";

								}

								

							}

							__finally

							{

								ReleaseMutex(MutexHandle);

							}

							InvalidateRect (hwnd, NULL, TRUE) ;

							return 0;



		case WM_DESTROY :

							UnmapViewOfFile(Image);

							CloseHandle(FileHandle);

							CloseHandle(MutexHandle);

							PostQuitMessage (0) ;

							return 0 ;

}



	return DefWindowProc (hwnd, iMsg, wParam, lParam) ;

}



Програма №2



LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;



HANDLE FileMappingHandle, FileHandle, MutexHandle;

LPVOID Image;

int *a;

std::string str="";







int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

	static char szAppName[] = "FileImageSorter" ;

HWND hwnd ;

MSG msg ;

WNDCLASSEX wndclass ;



wndclass.cbSize = sizeof (wndclass) ;

wndclass.style = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc = WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

wndclass.hInstance = hInstance ;

wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName = NULL ;

wndclass.lpszClassName = szAppName ;

wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;



RegisterClassEx (&wndclass) ;



hwnd = CreateWindow (szAppName, 

			 "FileImageSorter", 

				 WS_OVERLAPPEDWINDOW, 

					 10,						

						10,						

						170, 

						80, 

						NULL, 

						NULL, 

						hInstance, 

						NULL) ;		 



ShowWindow (hwnd, iCmdShow) ;

UpdateWindow (hwnd) ;



while (GetMessage (&msg, NULL, 0, 0))

{

		TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}



LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

	HDC hdc ;

PAINTSTRUCT ps ;

RECT rect ;



switch (iMsg)

{

		case WM_CREATE:

							

							return 0 ;



case WM_PAINT:

							hdc = BeginPaint (hwnd, &ps) ;

							GetClientRect (hwnd, &rect) ;

							TextOut(hdc, 10,10,str.c_str(),str.size());

							EndPaint (hwnd, &ps) ;

							return 0 ;



		 case WM_KEYDOWN:

							if(wParam==VK_SPACE)

							{

								FileMappingHandle=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "mass");

							if(FileMappingHandle==NULL)

							{

								MessageBox(hwnd, "Ошибка создания дескриптора проэцирования", "Ошибка", MB_ICONWARNING);

								exit(1);

							}

							Image=MapViewOfFile(FileMappingHandle, FILE_MAP_WRITE, 0, 0, 0);

							if(Image==NULL)

							{

								MessageBox(hwnd, "Ошибка проэцирования файла", "Ошибка", MB_ICONWARNING);

								exit(1);

							}

							MutexHandle=OpenMutex(MUTEX_ALL_ACCESS, FALSE, "massmutex"); 

							if(MutexHandle==NULL)

							{

								MessageBox(hwnd, "Невозможно создать мутекс", "Ошибка", MB_ICONWARNING);

								exit(1);

							}

								str="Работа начата...";

								InvalidateRect (hwnd, NULL, TRUE) ;

								__try

								{

									a= (int *)Image;

	

									long i, j;

									int x;

									for( i=1; i < 26; i++) 

										for( j = 26-1; j > i; j-- ) 

										{

											Sleep(200);

											__try

											{

												WaitForSingleObject(MutexHandle, INFINITE);

												if ( a[j-1] > a[j] ) 

												{

													x=a[j-1]; 

													a[j-1]=a[j]; 

													a[j]=x;	

													if(i==3)

														exit(1);

												}

											}

											__finally

											{

												ReleaseMutex(MutexHandle);

											}

										}

								}

								__finally

								{

									str="Работа закончена";

									UnmapViewOfFile(Image);

									CloseHandle(FileHandle);

									CloseHandle(MutexHandle);

								}

							} 

							InvalidateRect (hwnd, NULL, TRUE) ;

							return 0;



case WM_DESTROY:

							UnmapViewOfFile(Image);

							CloseHandle(FileHandle);

							CloseHandle(MutexHandle);

							PostQuitMessage (0) ;

							return 0 ;

}

	return DefWindowProc (hwnd, iMsg, wParam, lParam) ;

}




Вывод



Следовательно, во время выполнения данной лабораторной работы были получены практические навыки работы с многопоточным программированием. Был создан проект, который включает в себе две программы: одна программа – сортирует массив из файла, а другая выводит на экран содержание этого файла. Обе программы используют один и тот же файл в один момент времени.





1