[완료] pthread_mutex_lock ( )의 위치에 따라 다르게 출력되는 문제..

고양이를부탁해의 이미지

안녕하세요. *^^*

요즘 날씨도 꾸물꾸물한데 다들 별일 없으신가요?

제가 열혈강의 소켓 책으로 소켓프로그래밍을 한창 공부하고 있는데

멀티스레드에서의 동시접근 문제를 해결하기 위한 mutex 부분에서 이해가 되지 않는 부분이 있어 질문드립니다.

 pthread_create(&t1, NULL, thread_increment, &thread1);
 pthread_create(&t2, NULL, thread_increment, &thread2);
 
 void* thread_increment(void *arg)
 {
         int i;
         for(i=0; i<5; i++){
                 pthread_mutex_lock(&mutx);
                 sleep(1);
                 number++;
                 printf("excution : %s, number : %d\n",(char*)arg, number);
                 pthread_mutex_unlock(&mutx);
         }
 }

위 코드를 실행하면 다음과 같은 결과가 나옵니다
excution : A Thread, number : 1
excution : B Thread, number : 2
excution : A Thread, number : 3
excution : B Thread, number : 4
excution : A Thread, number : 5
excution : B Thread, number : 6
excution : A Thread, number : 7
excution : B Thread, number : 8
excution : A Thread, number : 9
excution : B Thread, number : 10


그 다음 sleep()에 주석을 하고 실행하거나 pthread_mutex_unlock(&mutx)의 위치를
printf() 위로 올리면 대부분의 경우 다음과 같이 출력됩니다.

excution : A Thread, number : 1
excution : A Thread, number : 2
excution : A Thread, number : 3
excution : A Thread, number : 4
excution : A Thread, number : 5
excution : B Thread, number : 6
excution : B Thread, number : 7
excution : B Thread, number : 8
excution : B Thread, number : 9
excution : B Thread, number : 10

먼저 pthread_mutex_lock()을 실행시킨 A가 락을 걸고 그 다음인 B가 대기하고 있다 A가 unlock를 실행하면
B가 대기상태를 풀고 임계영역을 실행해야 하는거라고 이해하고 있었는데 이해를 잘 못하고 있는거 같습니다.

pthread_mutex_lock,unlock의 위치가 스레드의 접근순서에 영향을 주는거 같은데 그 원리를 잘 모르겠습니다.
힌트를 좀 얻을 수 있을까요? 부탁드리겠습니다 ^_^/

rein의 이미지

pthread_mutex_unlock으로 릴리즈된 락을 어느 스레드가 잡을지는 OS의 스케쥴링 정책에만 영향을 받습니다.
즉 먼저 기다렸다고 먼저 잡는다는 보장이 없습니다.

고양이를부탁해의 이미지

좋은 답변 감사드립니다 ^^
그렇지만 릴리즈되는 시점에서 기다리고 있는 스레드는 하나뿐이지 않나요??
대기중이였던 스레드는 unlock을 실행한 스레드가 다시 루프를 돌아 다시 lock을 실행할때까지도
잡지 못할 수도 있다는 말씀이신가요??
------------
힘들면 즐겁다.


------------
힘들면 즐겁다.

rein의 이미지

첫번째 스레드가 루프가 끝나서 다시 pthread_mutex_lock 을 부르는 동안에 두번째 스레드가 실행된다는 보장이 없으면 마찬가지입니다;

고양이를부탁해의 이미지

아 보장이 안되는군요..그렇다면 pthread_mutex_unlock(&mutx)의 위치를 printf() 위로 올렸을 경우에도 저런 출력이 나오던데 이거 역시 같은 이유때문인가요??
------------
힘들면 즐겁다.


------------
힘들면 즐겁다.

grassman의 이미지

pthread_mutex_unlock에서 pthread_mutex_lock 사이의 구간에 sleep을 넣으면 됩니다.

지금은 mutex가 잠긴 상태에서 sleep을 하고 있어서 thread 전환이 되더라도 다시 thread 1이 실행 순서를 먼저 잡을 수 밖에 없습니다. (운 좋으면 thread 2로 전환될 수도 있습니다) unlock에서 lock 사이의 구간이 너무 짧은 시간에 끝나므로 loop의 실행 횟수를 늘리거나 그 사이에 sleep을 넣어서 원하는 동작을 수행할 수 있습니다.

고양이를부탁해의 이미지

mutex가 잠긴 상태에서 sleep을 하고 있어 thread 전환이 되더라도
다시 thread1이 실행순서를 잡을 수 밖에 없다고 하셨는데..
혹시 이유가 thread2가 오래 대기하고 있다보니 스케쥴링 우선순위가 thread1보다
밀려서 그런건가요??

------------
힘들면 즐겁다.


------------
힘들면 즐겁다.

winner의 이미지

mutex가 풀릴 때까지 못하죠.

pthread를 좀더 배우게 되면 조건변수를 배우게 될테고 그러면
원하시는 바를 정확히 하실 수 있을 겁니다.

jick의 이미지

sleep을 한다고 해서 "반드시" thread 전환이 된다는 보장은 없습니다. 테스트하고 있는 특정 시스템에서 높은 확률로 될 뿐이죠. 그 시스템의 library가 업그레이드되거나, load가 많이 걸리거나, 시스템을 바꾸거나 하면 언제든 깨질 수 있습니다.

thread를 쓰는 코드에서 "sleep을 넣어야 동작하는 코드"는 그냥 잘못된 코드라고 생각하는 게 속편합니다.

grassman의 이미지

급하게 글을 쓰느라 어감을 정확히 전달하지 못했군요.
다시 읽어보니 그렇게 해석이 되는 걸 알았습니다.
"반드시"는 "굳이"로 바꾸겠습니다.

지적 감사합니다.

고양이를부탁해의 이미지

많은 분들의 좋은 말씀 감사드립니다'ㅡ'/

------------
힘들면 즐겁다.


------------
힘들면 즐겁다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.