mutex lock & unlock에 대해서… (소스코드 있음)

dbsthqkf의 이미지

mutex lock과 unlock에 대해서 공부하고 있는데요…
mutex lock 과 unlock을 걸어서 0부터 10까지 출력시키는 건데
mutex lock과 unlock을 주석처리해도 똑같은 결과가 나오네요 ㅠ
thread1과 thread2가 동기화가 안되서 결과 값이 이상하게 나올줄 알았는데
lock과 unlock을 해줘도
thread 1 = 0
thread 2 = 1
thread 2 = 2
thread 1 = 3
.
.
.
thread 1 = 9
이렇게 나오고
lock과 unlock을 안해줘도 제대로 나오는것 같은데…
왜일까요?

#include
#include
#include

int ncount; // 쓰레드간 공유되는 자원
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 쓰레드 초기화

void* do_loop(void *data)
{
int i;
for (i = 0; i < 5; i++)
{
// pthread_mutex_lock(&mutex); // 잠금을 생성한다.
printf("loop1 : %d\n", ncount);
ncount ++;
if(i == 5) return;
// pthread_mutex_unlock(&mutex); // 잠금을 해제한다.
sleep(1);
}
}

void* do_loop2(void *data)
{
int i;

// 잠금을 얻으려고 하지만 do_loop 에서 이미 잠금을
// 얻었음으로 잠금이 해제될때까지 기다린다.
for (i = 0; i < 5; i++)
{
// pthread_mutex_lock(&mutex); // 잠금을 생성한다.
printf("loop2 : %d\n", ncount);
ncount ++;
// pthread_mutex_unlock(&mutex); // 잠금을 해제한다.
sleep(2);
}
}

int main()
{
int thr_id;
pthread_t p_thread[2];
int status;
int a = 1;

ncount = 0;
thr_id = pthread_create(&p_thread[0], NULL, do_loop, (void *)&a);
sleep(1);
thr_id = pthread_create(&p_thread[1], NULL, do_loop2, (void *)&a);

pthread_join(p_thread[0], (void *) &status);
pthread_join(p_thread[1], (void *) &status);
status = pthread_mutex_destroy(&mutex);
printf("code = %d\n", status); //join status
printf("programing is end\n");
return 0;
}

kukyakya의 이미지

소스 코드 부분을 [ code]로 묶어주시면 다른 분들이 보기에 더 편할 것 같습니다.

dbsthqkf의 이미지

글 수정이 안되네요 ㅠ
담엔 그렇게 하겠습니다 ^^

jick의 이미지

"mutex를 사용하지 않으면 프로그램이 오동작할 수 있다"라는 것이지, "mutex를 사용하지 않으면 프로그램이 *반드시* 오동작한다"가 아닙니다. (그렇게만 된다면 멀티쓰레드 디버깅이 얼마나 쉽겠습니까마는...)

주어진 프로그램을 보면 printf는 원래 내부적으로 락을 걸고 동작하니 결국 문제가 될 수 있는 문장은 ncount++뿐입니다. 이건 정수 변수 하나를 건드리는 연산이기 때문에 무척 빠르겠죠. (인텔 CPU라면 기계어 명령어 하나로 가능.) 그리고 앞뒤로 sleep(1) 혹은 sleep(2)가 들어가는데, 요즘 CPU에서 쓰레드 두 개가 1~2초씩 쉬고 나서 정수를 하나 증가시키려고 할 때 하필이면 정확히 같은 시간에 그 변수를 건드릴 확률은 아마 새 두 마리가 운동장을 날아다니다 같은 사람 머리에 똥을 쌀 확률 정도 되지 않을라나 싶습니다.

문제를 보고 싶으시면 sleep을 없애고 코어가 두 개 이상인 기계에서 루프 카운트를 1억 정도로 올려서 돌려보세요.

dbsthqkf의 이미지

아…….. 그렇군요 ㅠㅠ
답변 감사합니다.

댓글 달기

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