본문 바로가기
IT창고/System

스레드 풀링/이벤트(스레드 감시)

by 창구창고 2007. 1. 22.
반응형
/*#include<windows.h>
#include<stdio.h>

DWORD WINAPI foo(void *p)
{
	DWORD pid	=	(DWORD)p;

	HANDLE	hProcess	=	OpenProcess(PROCESS_ALL_ACCESS, 0 ,pid);

	if(hProcess == 0)
	{
		printf("Can't Get Process Handle...\n");
		return 0;
	}
	HANDLE	hEvent =	OpenEvent(EVENT_ALL_ACCESS,0,"EXIT_EVENT");
	HANDLE	h[2]	=	{	hProcess,hEvent	};

	DWORD ret =	WaitForMultipleObjects(2,h,FALSE,//둘중에 하나만 시그널 되면
										INFINITE);
	if(ret == WAIT_OBJECT_0)
	{
		printf("\n___%d번 프로세스가 종료 되었습니다. __\n",pid);
	}
	else if(ret == WAIT_OBJECT_0 + 1)
	{
		printf("EXIT_EVENT가 시그널 되어 종료 합니다.\n");
	}
	CloseHandle(hEvent);
	CloseHandle(hProcess);
	return 0;
}

void main()
{
	HANDLE hEvent	=	CreateEvent(0, TRUE, 0, "EXIT_EVENT");
	HANDLE hThread[1000];
	int Count = 0;
	system("ps");
	while(1)
	{
		printf("감시할 프로세스 ID를 넣어 주세요 >> " );

		DWORD pid;
		scanf("%d", &pid);
		if(pid	==	1)break;

		hThread[Count++]	=	CreateThread(0, 0, foo, (void *)pid, 0, 0);
		CloseHandle(hThread);
	}
	//대기중인 모든 스레드를 깨운다.
	SetEvent(hEvent);

	//모든 스레드가 정말로 종료 할때까지 기다린다.
	WaitForMultipleObjects(Count,hThread,TRUE, INFINITE);

	for(int i  = 0 ; i < Count ; i++)CloseHandle(hThread[i]);
}*/

/*
과제
감시 Thread를 만들어서 자고있는 스레드를 깨워서 추가 이벤트를 줘서 하나의 스레드가 64개의 프로세스를 감시하게 만들어라.
*/

/*
네트워크 프로그램들은
주 스레드는 감시만(대기) 하고 누군가 접속을 하면 자식 스레드를 만들어서 전송을 한다.
하지만 스레드를 계속 만드는게 좋을까? -> NO ->스레드수는 줄이고 적은 스레드들이 열개의 일을 할수있게 하는것 -> 스레드 풀링
*/

/*스레드 풀링*/
#include<iostream>
#include<queue>
#include<windows.h>
#include<conio.h>
using namespace std;

//------------------------------------------------------------------------------
//작업의 모양 (결국 작업이란 -> 함수를 의미);
typedef void(*WORK)();

queue<WORK> WORK_Q;
HANDLE	hSemaphore;

DWORD	WINAPI	Thread(void *p)
{
	while(1)
	{
		//작업 Q에 작업 들어오는 것을 대기한다.
		WaitForSingleObject(hSemaphore, INFINITE);

		WORK f	=	WORK_Q.front();
		WORK_Q.pop();

		f();//작업수행
	}
	return 0;
}
void InitPool(int n)
{
	hSemaphore	=	CreateSemaphore(0,0,1000,"WORK_COUNT");
	for(int i = 0; i < n ; ++i)
	{
		CloseHandle(CreateThread(0,0,Thread,0,0,0));
	}
}
void AddWork(WORK f)
{
	//작업 Q에 작업(함수주소)를 넣는다.
	WORK_Q.push(f);

	//세마포어를 증가해서 자고있는 스레드를 깨운다.
	LONG old;
	ReleaseSemaphore(hSemaphore, 1, &old);
}
//실제 작업함수
CRITICAL_SECTION cs;
void foo()
{
	for(int i = 0 ; i < 10 ; i++)
	{
		EnterCriticalSection(&cs);
		printf("%d : %d\n",GetCurrentThreadId(),i);
		fflush(stdout);
		LeaveCriticalSection(&cs);
		Sleep(1000);
	}
	return ;
}
void main()
{
	InitializeCriticalSection(&cs);
	InitPool(3);
	//5개의 작업을 큐에 넣는다.
	AddWork(foo);AddWork(foo);AddWork(foo);AddWork(foo);AddWork(foo);
	getch();
	DeleteCriticalSection(&cs);
}
/*원자 연산 Atomic operate
하나의 스레드가 하나의 연산의 수행을 끝낼때까지 인터럽트를 발생시키지 않게 한다.
InterlockedIncrement()
*/
반응형

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."