Синхронизация потоков в разных процессах
Министерство образования и науки Украины
Донецкий национальный технический университет
Факультет КНТ
Кафедра КСМ
Лабораторная работа №9, 10
на тему:
«Синхронизация потоков в одном процессе»
Выполнил студент
группы ПКД-09
Крайнюк Елена
Донецк
2011
Задание. Разработать многопоточное приложение Windows. Первый вторичный поток создаётся в приостановленном состоянии при обработке события WM_CREATE главного окна. С помощью пунктов меню пользователь может возобновить или приостановить работу этого потока. Второй поток создаётся при выборе соответствующего пункта меню. Потоковые функции вторичных потоков должны выполнять действия, описанные в варианте заданий. Синхронизировать работу первого и второго вторичных потоков таким образом, чтобы операции вывода в окно выполнялись сначала одной потоковой функцией определённое количество раз, потом другой и т.д. Объект, который управляет синхронизацией, и количество повторов взять по варианту.
8. Первый поток: перемещает квадрат со стороной 10 пикселей снизу-вверх и наоборот с интервалом 0,3 сек.
Второй поток: перемещает сектор эллипса (Pie) по боковой диагонали сверху вниз и наоборот с интервалом 0,3 сек.
№ | Количество повторов | Объект синхронизации |
8 | 5 | Семафор |
Программа:
|
|
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include "resource.h"
#include <stdlib.h>
char ClassNameMain[]="MainWindow";
HWND hWnd;
HINSTANCE hInst;
double xmin, xmax;
int penstyle, brushstyle;
HANDLE hFirstThread,hSecondThread;
HANDLE hSemaphor1, hSemaphor2;
static HWND hStaticX;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL RegWinClass(WNDPROC, LPCTSTR, UINT,HINSTANCE);
DWORD WINAPI ThreadFunc1(LPVOID params);
DWORD WINAPI ThreadFunc2(LPVOID params);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HMENU menu;
if(!RegWinClass((WNDPROC)WndProc, ClassNameMain, COLOR_WINDOW, hInstance))
{
MessageBox(NULL,"Регистрация главного окна не выполнена", NULL, MB_OK);
return false;
}
menu=LoadMenu(NULL,(LPCSTR)IDR_MENU1);
hWnd=CreateWindow(ClassNameMain,"Лабораторная работа №9",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,menu,hInstance,NULL);
if (!hWnd)
{
MessageBox(NULL,"Главное окно не создано", NULL,MB_OK);
return 0;
}
hSemaphor1=CreateSemaphore(NULL,1,1,NULL);
hSemaphor2=CreateSemaphore(NULL,0,1,NULL);
hInst = hInstance; // Store instance handle in our global variable
ShowWindow(hWnd,SW_SHOW);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
BOOL RegWinClass(WNDPROC proc, LPCTSTR lpszClassName, UINT hrBackGround, HINSTANCE hInst)
{
WNDCLASS w;
w.lpszClassName=lpszClassName;
w.hInstance=hInst;
w.lpfnWndProc=proc;
w.hCursor=LoadCursor(NULL, IDC_ARROW);
w.hIcon=LoadIcon(NULL, lpszClassName);
w.lpszMenuName=NULL;
w.hbrBackground=(HBRUSH)(hrBackGround+1);
w.style=CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
|
w.cbClsExtra=0;
w.cbWndExtra=0;
return (RegisterClass(&w)!=0);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(msg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_40002:
ResumeThread(hFirstThread);
break;
case ID_40003:
SuspendThread(hFirstThread);
break;
case ID_40004:
hSecondThread=CreateThread(NULL, 0, ThreadFunc2, NULL, NULL, NULL);
break;
case ID_40001:
DestroyWindow(hWnd);
break;
}
break;
case WM_CREATE:
hFirstThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc1,hWnd,CREATE_SUSPENDED,NULL);
break;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
DWORD WINAPI ThreadFunc1(PVOID pvParam)
{
HDC hDC;
HPEN pen1, pen2;
int x,y,revers;
RECT rt;
int j;
hDC=GetDC(hWnd);
GetClientRect(hWnd,&rt);
x=0;
y=rt.bottom-36;
revers=1;
pen1=CreatePen(PS_SOLID,1,RGB(0,25,176));
pen2=CreatePen(PS_NULL,1,0);
for(;;)
{WaitForSingleObject(hSemaphor1,INFINITE);
for(j=0;j<5;j++)
{
SelectObject(hDC,pen2);
Rectangle(hDC,x,y-1,x+12,y+12);
SelectObject(hDC,pen1);
Rectangle(hDC,x,y,x+10,y+10);
|
|
y-=revers;
if ( y<=0 || y>=rt.bottom)
{
revers=-revers;
}
}
ReleaseSemaphore(hSemaphor2,1,NULL);
}
ReleaseDC(hWnd,hDC);
return 0;
}
DWORD WINAPI ThreadFunc2(LPVOID Param)
{
HDC hDC;
HPEN pen1, pen2;
int x,y,revers;
RECT rt;
int j;
hDC=GetDC(hWnd);
GetClientRect(hWnd,&rt);
x=0;
y=rt.bottom-36;
revers=1;
pen1=CreatePen(PS_SOLID,1,RGB(255,0,0));
pen2=CreatePen(PS_NULL,1,0);
for(;;)
{WaitForSingleObject(hSemaphor2,INFINITE);
for(j=0;j<5;j++)
{
SelectObject(hDC,pen2);
Rectangle(hDC,x-1,y-1,x+38,y+38);
SelectObject(hDC,pen1);
Pie(hDC,x,y,x+36,y+36,(x+31),y,(x+31),y+36);
x+=revers;
y-=revers;
if (x>=rt.right || y<=0 || x<=0 || y>=rt.bottom)
{
revers=-revers;
}
}
ReleaseSemaphore(hSemaphor1,1,NULL);
}
ReleaseDC(hWnd,hDC);
return 0;
}
Синхронизация потоков в разных процессах
Задание. Изменить лабораторную работу №9 следующим образом:
– написать новое приложение, вторичный поток которого будет выполнять те же действия, что и второй вторичный поток из лабораторной работы №9;
– по пункту меню, по которому в лабораторной работе №9 запускался второй вторичный поток, запустить приложение из предыдущего пункта;
|
|
– синхронизировать работу «Первого потока» из родительского процесса и вторичного потока из дочернего потока таким образом, чтобы операции вывода в окно выполнялись сначала одной потоковой функцией определённое количество раз, потом другой и т.д.
1 приложение:
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include "resource.h"
#include <stdlib.h>
char ClassNameMain[]="MainWindow";
HWND hWnd;
HINSTANCE hInst;
double xmin, xmax;
int penstyle, brushstyle;
HANDLE hFirstThread,hSecondThread;
HANDLE hSemaphor1, hSemaphor2;
static HWND hStaticX;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL RegWinClass(WNDPROC, LPCTSTR, UINT,HINSTANCE);
DWORD WINAPI ThreadFunc1(LPVOID params);
DWORD WINAPI ThreadFunc2(LPVOID params);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HMENU menu;
if(!RegWinClass((WNDPROC)WndProc, ClassNameMain, COLOR_WINDOW, hInstance))
{
MessageBox(NULL,"Регистрация главного окна не выполнена", NULL, MB_OK);
return false;
}
menu=LoadMenu(NULL,(LPCSTR)IDR_MENU1);
hWnd=CreateWindow(ClassNameMain,"Лабораторная работа №10(1)",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,menu,hInstance,NULL);
if (!hWnd)
{
MessageBox(NULL,"Главное окно не создано", NULL,MB_OK);
return 0;
}
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;
hSemaphor1=CreateSemaphore(&sa,1,1,"PERVIY");
hSemaphor2=CreateSemaphore(&sa,0,1,"VTOROY");
hInst = hInstance; // Store instance handle in our global variable
ShowWindow(hWnd,SW_SHOW);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
BOOL RegWinClass(WNDPROC proc, LPCTSTR lpszClassName, UINT hrBackGround, HINSTANCE hInst)
{
WNDCLASS w;
w.lpszClassName=lpszClassName;
w.hInstance=hInst;
w.lpfnWndProc=proc;
w.hCursor=LoadCursor(NULL, IDC_ARROW);
w.hIcon=LoadIcon(NULL, lpszClassName);
w.lpszMenuName=NULL;
w.hbrBackground=(HBRUSH)(hrBackGround+1);
w.style=CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
w.cbClsExtra=0;
w.cbWndExtra=0;
return (RegisterClass(&w)!=0);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
DWORD dwThreadID;
char str[11],cmdline[21];
switch(msg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_40002:
ResumeThread(hFirstThread);
break;
case ID_40003:
SuspendThread(hFirstThread);
break;
case ID_40004:
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
ZeroMemory(&pi,sizeof(pi));
sprintf(cmdline,"№2.exe");
CreateProcess(NULL,cmdline,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi);
break;
case ID_40001:
DestroyWindow(hWnd);
break;
}
break;
case WM_CREATE:
hFirstThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc1,hWnd,CREATE_SUSPENDED,NULL);
break;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
DWORD WINAPI ThreadFunc1(PVOID pvParam)
{ HDC hDC;
HPEN pen1, pen2;
int x,y,revers;
RECT rt;
int j;
hDC=GetDC(hWnd);
GetClientRect(hWnd,&rt);
x=0;
y=rt.bottom-36;
revers=1;
pen1=CreatePen(PS_SOLID,1,RGB(0,25,176));
pen2=CreatePen(PS_NULL,1,0);
for(;;)
{ WaitForSingleObject(hSemaphor1,INFINITE);
for(j=0;j<5;j++)
{
SelectObject(hDC,pen2);
Rectangle(hDC,x,y-1,x+12,y+12);
SelectObject(hDC,pen1);
Rectangle(hDC,x,y,x+10,y+10);
Sleep(300);
y-=revers;
if ( y<=0 || y>=rt.bottom)
{
revers=-revers;
}
}
ReleaseSemaphore(hSemaphor2,1,NULL);
}
ReleaseDC(hWnd,hDC);
return 0;
}
2 приложение:
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include "resource.h"
#include <stdlib.h>
char ClassNameMain[]="MainWindow";
HWND hWnd;
HINSTANCE hInst;
double xmin, xmax;
int penstyle, brushstyle;
HANDLE hFirstThread;
HANDLE hSemaphor1=0, hSemaphor2=0;
static HWND hStaticX;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL RegWinClass(WNDPROC, LPCTSTR, UINT,HINSTANCE);
DWORD WINAPI ThreadFunc1(LPVOID params);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HMENU menu;
if(!RegWinClass((WNDPROC)WndProc, ClassNameMain, COLOR_WINDOW, hInstance))
{
MessageBox(NULL,"Регистрация главного окна не выполнена", NULL, MB_OK);
return false;
}
menu=LoadMenu(NULL,(LPCSTR)IDR_MENU1);
hWnd=CreateWindow(ClassNameMain,"Лабораторная работа №10(2)",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,menu,hInstance,NULL);
if (!hWnd)
{
MessageBox(NULL,"Главное окно не создано", NULL,MB_OK);
return 0;
}
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;
hSemaphor1=CreateSemaphore(&sa,1,1,"PERVIY");
hSemaphor2=CreateSemaphore(&sa,0,1,"VTOROY");
hInst = hInstance; // Store instance handle in our global variable
ShowWindow(hWnd,SW_SHOW);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
BOOL RegWinClass(WNDPROC proc, LPCTSTR lpszClassName, UINT hrBackGround, HINSTANCE hInst)
{
WNDCLASS w;
w.lpszClassName=lpszClassName;
w.hInstance=hInst;
w.lpfnWndProc=proc;
w.hCursor=LoadCursor(NULL, IDC_ARROW);
w.hIcon=LoadIcon(NULL, lpszClassName);
w.lpszMenuName=NULL;
w.hbrBackground=(HBRUSH)(hrBackGround+1);
w.style=CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
w.cbClsExtra=0;
w.cbWndExtra=0;
return (RegisterClass(&w)!=0);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
DWORD dwThreadID;
switch(msg)
{
case WM_CREATE:
hFirstThread=CreateThread(NULL, 0, ThreadFunc1, NULL, NULL, NULL);
break;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
DWORD WINAPI ThreadFunc1(LPVOID Param)
{
HDC hDC;
HPEN pen1, pen2;
int x,y,revers;
RECT rt;
int j;
hDC=GetDC(hWnd);
GetClientRect(hWnd,&rt);
x=0;
y=rt.bottom-36;
revers=1;
pen1=CreatePen(PS_SOLID,1,RGB(255,0,0));
pen2=CreatePen(PS_NULL,1,0);
for(;;)
{WaitForSingleObject(hSemaphor2,INFINITE);
for(j=0;j<5;j++)
{ SelectObject(hDC,pen2);
Rectangle(hDC,x-1,y-1,x+38,y+38);
SelectObject(hDC,pen1);
Pie(hDC,x,y,x+36,y+36,(x+31),y,(x+31),y+36);
Sleep(300);
x+=revers;
y-=revers;
if (x>=rt.right || y<=0 || x<=0 || y>=rt.bottom)
{
revers=-revers;
}
}
ReleaseSemaphore(hSemaphor1,1,NULL);
}
ReleaseDC(hWnd,hDC);
return 0;
}
Дата добавления: 2018-04-05; просмотров: 278; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!