pthread_cond_signal은 동시에 여러개의thread 를못깨우나요?

iamslash의 이미지

pthread_cond_wait 을 이용해서 100개의 thread 가 기다리고 있습니다. 기다리는 thread들은 동작했을때 처리시간이 100초 정도 걸립니다. 이때 다른 thread가 pthread_cond_signal 을 1초 간격으로 호출하면 기다리는 thread가 한개씩만 깨어납니다. 즉 하나 깨어나서 100초 지난후 처리 완료되고 또 하나가 깨어 납니다. 제가 바라는 것은 pthread_cond_signal 한만큼 동시에 깨어나서 각자 알아서들 처리하는 건데요... 조언좀 주세요...

xjiwoox의 이미지

방금 iamslash님이 올리신 글 바로 위의 질문에 답변을 했는데... 이 글을 보니
질문의 의도가 다른 것이었군요.

pthread_cond_signal()이 pthread_cond_wait()로 인해 이벤트 대기상태인
thread중 하나를 깨우는(?) 것은 맞습니다만.. condition value의 구조특성상
mutex와 연계되어 있기 때문에 첫번째 이벤트 발생으로 wait상태에서 풀려난
스레드는 pthread_cond_wait()이 리턴되면서 연계된 mutex의 lock을
얻습니다. 때문에 같은 mutex와 같은 condition value를 참조하고 있는 모든
thread들은 pthread_cond_signal()로부터 이벤트를 받더라도 mutex의
lock를 얻으려고 하므로 첫 번째 thread가 mutex를 unlock할 때까지
pthread_cond_wait()함수가 리턴되지 않고 그 밑의 코드들도 수행되지
않는 것입니다. iamslash님의 경우에는 100초동안 이 상태가 유지 되겠네요.
mutex로 임계영역을 설정하실 때 그 영역을 분할하여 쓰신다던가, 아니면
임계영역으로 보호할 부분만 한군데로 모아서 처리하시고 unlock해주시는게
좋을 것 같습니다.

s(˘∼˘*)z,·´″"`°³о$ √(´∀`√)... (˘ヘ˘ㆀ)a

stoneshim의 이미지

음.. 좀 이상하군요.

대개 condition을 wait하는 thread 측의 코드는

pthread_mutex_lock( &mutex );
pthread_cond_wait( &cond, &mutex );
pthread_mutex_unlock( &mutex );
/* 확인 과정을 위해 wait 부분을 looping 처리 하기도 합니다만 여기선 생략합니다. */

이런 형태이고, condition signal을 발생시키는 thread 측의 코드는

pthread_mutex_lock( &mutex );
pthread_cond_signal( &cond );
pthread_mutex_unlock( &mutex );

이런 형태인데...왜 그런일이 발생하죠?

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

shkwon81의 이미지

Quote:
제가 바라는 것은 pthread_cond_signal 한만큼 동시에 깨어나서 각자 알아서들 처리하는 건데요... 조언좀 주세요...

pthread_cond_signal()은 호출한 순간에 명시되어 있는 조건 변수에서 블록되어 있는 단 하나의 쓰레드만을 깨웁니다.

제 생각엔 원하시는 것은, 어느 순간에 pthread_cond_signal()을 호출하던지에 상관 없이, 10번 호출했다면 10개의 쓰레드를 깨우게끔 하고 싶다는 얘기 같은데요.. 제가 생각한 상황이 맞는지요?

그렇다면, pthread_cond_signal() 보다는 pthread_cond_broadcast()를 이용해 보세요..

그리고, pthread_cond_wait() 는 그 순간에 단 하나의 조건 변수 블록된 쓰레드만을 깨우는 것이지 "특정 숫자" 라는 개념이 없습니다.

따라서,

int sig_count; /* 시그널이 보내진 횟수(작업 가능량) 카운트 */

이런 변수를 두시고, 시그널을 보내는 쓰레드는, 시그널을 보내는 조건이 성립하면 다음과 같이 합니다.

pthread_mutex_lock(&mutex);
...
sig_count++;
pthread_cond_broadcast(&cond);
...
pthread_mutex_unlock(&mutex);

이제 작업 쓰레드는 다음과 같이 합니다.

pthread_mutex_lock(&mutex);
...
while (sig_count <= 0)
    pthread_cond_wait(&cond, &mutex);
sig_count--;
...
pthread_mutex_unlock(&mutex);

위와 같이 하면, cond 에서 대기 중인 모든 쓰레드들은 시그널이 브로드캐스트될 때마다 깨어나서, sig_count를 테스트해 보고는, sig_count의 수만큼만 실행될 것입니다. 물론 sig_count가 이미 0보다 크다면 cond에서 대기할 필요도 없겠지요 ^^

물론, 이제 더 이상 pthread_cond_broadcast() 가 호출되는 시점은 문제가 되지 않구요.. 답변이 되었기를 바랍니다.

xjiwoox의 이미지

Quote:
음.. 좀 이상하군요.

대개 condition을 wait하는 thread 측의 코드는

코드:
pthread_mutex_lock( &mutex );
pthread_cond_wait( &cond, &mutex );
pthread_mutex_unlock( &mutex );
/* 확인 과정을 위해 wait 부분을 looping 처리 하기도 합니다만 여기선 생략합니다. */

이런 형태이고, condition signal을 발생시키는 thread 측의 코드는

코드:
pthread_mutex_lock( &mutex );
pthread_cond_signal( &cond );
pthread_mutex_unlock( &mutex );

이런 형태인데...왜 그런일이 발생하죠?

대게는 pthread_cond_wait()과 pthread_mutex_unlock() 사이에
임계영역을 설정하는 경우가 많기 때문입니다.

pthread_mutex_lock( &mutex ); 
pthread_cond_wait( &cond, &mutex ); 

... /* 임계영역 */

pthread_mutex_unlock( &mutex ); 

s(˘∼˘*)z,·´″"`°³о$ √(´∀`√)... (˘ヘ˘ㆀ)a

stoneshim의 이미지

xjiwoox wrote:
대게는 pthread_cond_wait()과 pthread_mutex_unlock() 사이에
임계영역을 설정하는 경우가 많기 때문입니다.
pthread_mutex_lock( &mutex ); 
pthread_cond_wait( &cond, &mutex ); 

... /* 임계영역 */

pthread_mutex_unlock( &mutex ); 

mutex 를 condition variable 용으로만 사용하지 않고, 다른 자원의 locking 용도에 함께 사용하는 경우라면 그럴수도 있겠군요. ( 제가 맞게 받아들인 겁니까? 그렇다면, 이런식으로 사용하지 않고 condition variable만을 위한 mutex를 사용하는것이 바람직하지 않을까요?)

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

xjiwoox의 이미지

Quote:
mutex 를 condition variable 용으로만 사용하지 않고, 다른 자원의 locking 용도에 함께 사용하는 경우라면 그럴수도 있겠군요. ( 제가 맞게 받아들인 겁니까? 그렇다면, 이런식으로 사용하지 않고 condition variable만을 위한 mutex를 사용하는것이 바람직하지 않을까요?)

네 맞습니다.. condition value 를 체크하기 위한 mutex와 shared data
처리를 위한 mutex를 따로 두어 사용한다면 해결될 수 있는 문제입니다.
다만, 일반적으로 thread pool을 구성할 때 main thread에서 각각의
thread로 signal을 전달하기 전에 건네줄 shared data(task)에 대한
수정작업이 이뤄지는 경우가 많기 때문에(socket descriptor와 같은...)
이 수정작업을 condition value처리를 위해 쓰는 mutex의 임계영역 안에서
처리하는 경우가 많고(실제로 socket descript를 넘겨받는 정도의 작업은
아주 짧은 순간에 이루어지기 때문에...), 그렇게 처리해도 문제가 없습니다.
다만... 임계영역에 속하는 코드가 오랜 실행시간을 요구한다면 따로 mutex나
semaphore등을 통한 별도의 동기화 처리가 필요하겠죠.

s(˘∼˘*)z,·´″"`°³о$ √(´∀`√)... (˘ヘ˘ㆀ)a

김성진의 이미지

제가 자세히 님의 로직을 모르겠지만,

세마포어를 쓰시는 게 더 좋을 듯 합니다.

조건변수는 님의 용도에 맞지 않는 듯 하네요.

만일 굳이 조건변수를 쓰시려면 해당 쓰레드 마다

Mutex를 1개씩 두시면 될 것 이라고 생각합니다.

timeout에 대한 요구사항이 없다면 더더욱 그렇습니다.

고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.