/**
libevet 멀티 쓰레드 사용코자 했는데, 이것이 생각 처럼 동작
하지 않았다. connection이 하나만 들어 왔을 때는 정상동작 했지만, 둘 이
상이되면서 부터는 event_dispatch() 에서 1을 리턴(set 되어 있는 이벤트
가 없다라는 의미)하면서 계속 종료 되었다.
혹시나 싶어 의 멀티 쓰레드 환경에 대해 찾아 보니 아래와 같은
글이 있어 짧은 영어 실력이나마 번역을 해 보았다.
혹시나 누군가가 잘 못된 내용을 진실로 받아 들이고 그걸 다른 사람에게
진실인양 전파 한다면 세상에 잘못된 지식들이 판치게 되고, 지식을 추구하
는 사람들에게 있어 그것만큼 나쁜 일이 없다.
아래의 글 중 잘 못된 내용이 있다면 언제든지 kukuta@gmail.com으로 알
려주면 고맙겠다.
*/
As the guy who added thread support to memcached, I feel qualified to
answer this one:
memcached( 이용해서 만든 일종의 메모리 DB)에 멀티쓰레드를
사용하려는 사람들에게 추천합니다.
What doesn't support is sharing a instance across
threads. It works just fine to use in a multithreaded process
where only one thread is making calls.
는 쓰레드간에 공유를 지원히지 않습니다. 만일 당신이 쓰레드를 써
야 하겠다면 한 쓰레드만이 호출하도록 만들어야 합니다.
What also works, and this is what I did in memcached, is to use multiple
instances of . Each call to event_init() will give you back an
"event base," which you can think of as a handle to a instance.
(That's documented in the current manual page, but NOT in the older
manpage on the home page.) You can have multiple threads each
with its own event base and everything works fine, though you probably
don't want to install signal handlers on more than one thread.
이것이 제가 memcached에서 인스턴스를 여러개 만들어서 사용하
려는 이유입니다. 각각 event_init() 호출은 개개별로 "event base" 객체를 생
성 합니다(이것은 요즘에 나오는 man page에도 기록되어 있습니다).
이런 방법으로 각각의 event base 가진 쓰레드를 생성 할 수 있으며, 비록
signal handler 하나의 쓰레드 이상에 인스톨 하는 것을 원치 않았더라도,
모든 것들이 순조롭게 잘 돌아 갈겁니다.
In the case of memcached, I allocate one event base per thread at
startup time. One thread handles the TCP listen socket; when a new
request comes in, it calls accept() then hands the file descriptor to
another thread to handle from that point on -- that is, each client is
bound to a particular thread. All you have to do is call
event_base_set() after you call event_set() and before you call event_add().
memcached의 경우, 나는 쓰레드의 시작점에서 event base 각 쓰레드 마다
할당 했습니다. 하나의 쓰레드가 listen 소켓을 들고, 새로운 접속이 시도 될 때
accept() 호출 하고 파일디스크립터(클라이언트소켓)을 생성하여 다른 쓰레드
에 넘깁니다. 이런 식으로 해서 각 클라이언트는 각자의 쓰레드에 바인드 됩니다.
여기서 해야 할 일은 event_set()함수 호출 후 event_add() 호출 하기 전에
event_base_set() 호출하는 것 뿐입니다.
Unfortunately, you pretty much have to use pipe() to communicate between
threads, That's a limitation, and honestly it's a pretty big
one: it makes a master/worker thread architecture, where one thread
handles all the I/O, much less efficient than you'd like. My initial
implementation in memcached used an architecture like that and it chewed
lots of CPU time. That's not really libevent's fault -- no UNIX-ish
system I'm aware of has an equivalent to the Windows
WaitForMultipleObjects API that allows you to wake up on semaphores /
condition variables and on input from the network. Without that, any
solution is going to end up using pipes (or maybe signals, which have
their own set of issues in a multithreaded context) to wake up the
threads.
하지만 불행하게도, 쓰레드간의 통신에는 pipe() 사용해야만 합니다.
그게 한계점이고, 상당히 까칠합니다. 이런 이유로 하나의 쓰레드가 모든 IO 쓰레
드들을 관리 하는 master/worker 쓰레드 아키텍쳐가 만들어 졌는데, 이게 성능에
있어서 또한 상당히 까칠 합니다. CPU 많이 잡아 먹는다는 말입니다. 이것은
결코 의 결함이 아닙니다. 어떤 UNIX-ish(?) 시스템에서도 윈도우의
WaitForMutipleObject API 같이 세마포어/condition variables wake 할수 있는
기능을 제공 하지 않습니다. WaitForMultipleObject 같은 지원이 없고서는 어떠한
시도도 결국 pipe 사용하는 것으로 끝났습니다(그렇지 않다면 아마도 각각의
쓰레드 마다 발행 셋(?set of issues) 가진 signal을 이용하던지 말입니다)
-Steve
원문 보기 : http://monkeymail.org/archives/ -users/2007-January/000450.html
추가 사항 : 2007. 3. 9 : 가 사용하고 있는 epoll 라이브러리 자체는 threadsafe하다고 한다.
http://www-gatago.com/linux/kernel/6116742.html
libevet 멀티 쓰레드 사용코자 했는데, 이것이 생각 처럼 동작
하지 않았다. connection이 하나만 들어 왔을 때는 정상동작 했지만, 둘 이
상이되면서 부터는 event_dispatch() 에서 1을 리턴(set 되어 있는 이벤트
가 없다라는 의미)하면서 계속 종료 되었다.
혹시나 싶어 의 멀티 쓰레드 환경에 대해 찾아 보니 아래와 같은
글이 있어 짧은 영어 실력이나마 번역을 해 보았다.
혹시나 누군가가 잘 못된 내용을 진실로 받아 들이고 그걸 다른 사람에게
진실인양 전파 한다면 세상에 잘못된 지식들이 판치게 되고, 지식을 추구하
는 사람들에게 있어 그것만큼 나쁜 일이 없다.
아래의 글 중 잘 못된 내용이 있다면 언제든지 kukuta@gmail.com으로 알
려주면 고맙겠다.
*/
As the guy who added thread support to memcached, I feel qualified to
answer this one:
memcached( 이용해서 만든 일종의 메모리 DB)에 멀티쓰레드를
사용하려는 사람들에게 추천합니다.
What doesn't support is sharing a instance across
threads. It works just fine to use in a multithreaded process
where only one thread is making calls.
는 쓰레드간에 공유를 지원히지 않습니다. 만일 당신이 쓰레드를 써
야 하겠다면 한 쓰레드만이 호출하도록 만들어야 합니다.
What also works, and this is what I did in memcached, is to use multiple
instances of . Each call to event_init() will give you back an
"event base," which you can think of as a handle to a instance.
(That's documented in the current manual page, but NOT in the older
manpage on the home page.) You can have multiple threads each
with its own event base and everything works fine, though you probably
don't want to install signal handlers on more than one thread.
이것이 제가 memcached에서 인스턴스를 여러개 만들어서 사용하
려는 이유입니다. 각각 event_init() 호출은 개개별로 "event base" 객체를 생
성 합니다(이것은 요즘에 나오는 man page에도 기록되어 있습니다).
이런 방법으로 각각의 event base 가진 쓰레드를 생성 할 수 있으며, 비록
signal handler 하나의 쓰레드 이상에 인스톨 하는 것을 원치 않았더라도,
모든 것들이 순조롭게 잘 돌아 갈겁니다.
In the case of memcached, I allocate one event base per thread at
startup time. One thread handles the TCP listen socket; when a new
request comes in, it calls accept() then hands the file descriptor to
another thread to handle from that point on -- that is, each client is
bound to a particular thread. All you have to do is call
event_base_set() after you call event_set() and before you call event_add().
memcached의 경우, 나는 쓰레드의 시작점에서 event base 각 쓰레드 마다
할당 했습니다. 하나의 쓰레드가 listen 소켓을 들고, 새로운 접속이 시도 될 때
accept() 호출 하고 파일디스크립터(클라이언트소켓)을 생성하여 다른 쓰레드
에 넘깁니다. 이런 식으로 해서 각 클라이언트는 각자의 쓰레드에 바인드 됩니다.
여기서 해야 할 일은 event_set()함수 호출 후 event_add() 호출 하기 전에
event_base_set() 호출하는 것 뿐입니다.
Unfortunately, you pretty much have to use pipe() to communicate between
threads, That's a limitation, and honestly it's a pretty big
one: it makes a master/worker thread architecture, where one thread
handles all the I/O, much less efficient than you'd like. My initial
implementation in memcached used an architecture like that and it chewed
lots of CPU time. That's not really libevent's fault -- no UNIX-ish
system I'm aware of has an equivalent to the Windows
WaitForMultipleObjects API that allows you to wake up on semaphores /
condition variables and on input from the network. Without that, any
solution is going to end up using pipes (or maybe signals, which have
their own set of issues in a multithreaded context) to wake up the
threads.
하지만 불행하게도, 쓰레드간의 통신에는 pipe() 사용해야만 합니다.
그게 한계점이고, 상당히 까칠합니다. 이런 이유로 하나의 쓰레드가 모든 IO 쓰레
드들을 관리 하는 master/worker 쓰레드 아키텍쳐가 만들어 졌는데, 이게 성능에
있어서 또한 상당히 까칠 합니다. CPU 많이 잡아 먹는다는 말입니다. 이것은
결코 의 결함이 아닙니다. 어떤 UNIX-ish(?) 시스템에서도 윈도우의
WaitForMutipleObject API 같이 세마포어/condition variables wake 할수 있는
기능을 제공 하지 않습니다. WaitForMultipleObject 같은 지원이 없고서는 어떠한
시도도 결국 pipe 사용하는 것으로 끝났습니다(그렇지 않다면 아마도 각각의
쓰레드 마다 발행 셋(?set of issues) 가진 signal을 이용하던지 말입니다)
-Steve
원문 보기 : http://monkeymail.org/archives/ -users/2007-January/000450.html
추가 사항 : 2007. 3. 9 : 가 사용하고 있는 epoll 라이브러리 자체는 threadsafe하다고 한다.
http://www-gatago.com/linux/kernel/6116742.html