>
Programming/C++

C++ 멀티쓰레드 기초적인 부분 간단 정리

쓰레드 생성


Win32 API에서는 CreateThead()함수를 사용한다

일반적으로 윈도우환경에서 process.h 헤더를 인클루드해주고 _beginthreadex()를 많이 쓴다(_beginthread() 함수의 단점을 보완한 함수)

일반적인 _beginthreadex() 함수는 HANDLE값을 리턴하며 쓰레드의 함수가 끝날때는 _endthreadex()를 호출해주는 것 대신 return만 해줘도 된다

리눅스에서는 pThread를 사용하는데 윈도우에서도 라이브러리만 설치하면 똑같이 사용가능하다고 한다

정확히 기억나지 않는데 C++11부터였나? OS와는 상관없이 사용할 수 있는 thread.h 헤더에 스레드 관련 라이브러리가 추가되어 이를 사용하여 새로운 쓰레드를 만들 수도 있다.


참고 사이트들

http://blog.naver.com/limsk112/70107328764

http://plming.tistory.com/62

http://blog.naver.com/pkban/220261870792



WaitForSingleObject()와 WaitForMultipleObjects() 함수
간단한 프로그램을 짜면 main쓰레드가 먼저 끝나버릴 수가 있기 때문에 사용해야한다.
즉 다른 스레드가 끝났는지 확인해서 끝날때까지 블로킹 해준다.
signaled 상태이면 non-signaled 로 전환을 한다
non-signaled 상태이면 블로킹이 되어 signaled 상태가 될때까지 기다린다.
그리고 또한 타임 아웃 설정을 할 수 있다.
WaitForSingleObject()은 하나의 쓰레드를 확인할 수 있다.
하지만 WaitForMultipleObjects()의 경우에는 여러개의 쓰레드를 확인할 수 있는 함수이다

참고 사이트


유저 모드와 커널 모드

유저 모드와 커널모드에 대해서 퍼온다면...


메모리 영역은 사용자에 의해서 할당되는 메모리 공간인 유저 영역과 운영체제라는 하나의 소프트웨어를 실행시키기 위해서 필요한 메모리 공간인 커널 영역으로 나뉜다.

사용자가 사용하는 메모리 영역은 유저 영역이지만 C언어는 메모리 참조가 용이하기 때문에 안정성 제공 측면에서 커널 모드와 유저 모드가 사용된다.

기본적으로 유저 모드로 동작하다가 Windows 커널이 실행되어야 하는 경우에 커널 모드로의 전환이 일어난다

모드 전환시 시스템에 부담을 줄 수 있다

[출처] 커널 레벨(Kernel Level) 쓰레드와 유저 레벨(User Level) 쓰레드|작성자 cmw1728



유저모드

일반적인 프로그램의 실행 모드, 시스템 리소스로의 접근이 허용되지 않는다.

커널모드에 비해 속도가 빠르다

유저모드로 크리티컬 섹션이 있다.


커널모드

시스템 리소스로의 접근을 위한 프로세스의 실행 모드, 커널 오브젝트를 통한 시스템 리소스로(File, Thread 등등)의 접근 시 유저모드에서 커널 모드로의 변환이 발생한다.

뮤텍스, 이벤트, 세마포어 등이 커널모드이다.


참고 사이트

http://blog.naver.com/cmw1728/220475950348



크리티컬 섹션
크리티컬 섹션은 열쇠에 많이 비유한다.(이 편이 이해하기 쉽다고 생각함)
밑에 다른 동기화기법들과 비교하면 가장 간단하고 가장 빠르다
핸들을 사용하지 않고 CRITICAL_SECTION이라는 자료형을 사용한다

InitializeCriticalSection(); - 키를 만든다
EnterCriticalSection(); - 키를 가지고 들어간다
LeaveCriticalSection(); - 키를 가지고 나온다
DeleteCriticalSection(); - 키를 없앤다
http://blog.naver.com/cmw1728/220479810666

뮤텍스
signaled 상태일 때 WaitForSingleObject()함수를 통과함.
이 때 non-signaled 상태로 전환되어 다른 스레드에서의 접근을 막는다.
​작업이 끝나면 ReleaseMutex()함수를 이용해 다시 signaled 상태로 전환한다​.
자신이 소유한 스레드를 알고 있고 같은 스레드가 같은 뮤텍스를 중복호출해도 데드락이 걸리지 않으며 내부적인 카운드를 증가시켜 0이 되어야 signaled 상태가 된다.
이름을 지어줄 수도 있다


이벤트

윈도우의 이벤트를 생각하면 이해하기 쉽다.

CreateEvent() 함수로 이벤트 핸들을 만든다

두번째 인자를 false로 하면 함수가 끝나면 자동으로 reset()이 되고 true이면 수동으로 SetEvent()와 ResetEvent()로 signaled과 non-signaled을 설정해줘야한다

SetEvent()는 signaled로 전환함

ResetEvent()는 non-signaled로 전환함




세마포어
세마포어는 동시에 여러 쓰레드에서 사용 할 수 있고 그 수를 초기에 설정할 수 있다.
값이 0이면 non-signaled 상태가 되어 WaitForSingleObject()에서 블로킹이 되고 1이상일경우 signaled 상태가 된다.
쓰레드에서 하나씩 접근할때마다 값이 1씩 감소하며 0이 되면 접근하는 쓰레드들은 대기를 하도록 한다.
ReleaseSemaphore()함수를 통해 카운트를 설정한 값만큼 올려줄 수 있다.



동기화 기법 전체 참고

http://blog.naver.com/tjddk417/150083792429


(네이버 블로그 - 2016.02.14. 23:19)



 [ 1 ]  [ 2 ]  [ 3 ]  [ 4 ]  [ 5 ]  [ 6 ]  [ ··· ]  [ 14 ] 

최근 트랙백

알림

이 블로그는 구글에서 제공한 크롬에 최적화 되어있고, 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.

태그

카운터

Today : 45
Yesterday : 58
Total : 126,083