본문 바로가기
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()
    */
    반응형

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