Синхронизация потоков в разных процессах

Министерство образования и науки Украины

Донецкий национальный технический университет

 

Факультет КНТ

Кафедра КСМ

 

 

Лабораторная работа №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; Мы поможем в написании вашей работы!

Поделиться с друзьями:




Мы поможем в написании ваших работ!