안녕하세요. pthread_cond_wait 에 관한 질문입니다.

lootpiz의 이미지

안녕하세요.
임계영역 설정에 관한 소스 입니다.
interleaving이 일어나지 않아서 결과가 10000이 찍혀야 하는데,
pthread_cond_wait에 익숙치 않아서 여쭈어봅니다.
pthread_cond_wait은 내부적으로 mutex를 unlock 시키고, waiting 한다는데,
어디서 잘못 되었는지 모르겠습니다.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
 
void* function(void* ptr);
void P(int* semaphore);
void V(int* semaphore);
 
pthread_mutex_t mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition = PTHREAD_COND_INITIALIZER;
int conditionMet = 0; 
int accnt1 	 = 0;
int accnt2 	 = 0;
 
int main(int argc, char** argv)
{
	pthread_t thread1, thread2;
	char* message1 = "Thread1";
	char* message2 = "Thread2";
	pthread_create( &thread1, NULL, function, (void*)message1 );
	pthread_create( &thread2, NULL, function, (void*)message2 );
	pthread_join(thread1, NULL);
	pthread_join(thread2, NULL);
	return 0;
}
 
void* function(void* ptr)
{
	int sum;
	int semaphore = 1;
	int counter = 0;
 
	do{
		int r = rand();
		P(&semaphore);
			int tmp1 = accnt1;
			int tmp2 = accnt2;
			accnt1 = tmp1 + r;
			accnt2 = tmp2 - r;
			sum  = accnt1 + accnt2;
		V(&semaphore);
	}while(sum == 0 && ++counter < 10000);
	printf("%s::COUNTER >> %d\n", (char*)ptr, counter);
}
void P(int* semaphore)
{
	pthread_mutex_lock(&mutex);
	*semaphore = *semaphore - 1;
	if(*semaphore < 0)
	{
		pthread_mutex_unlock(&mutex);
		if(!conditionMet) pthread_cond_wait(&condition, &mutex);
	}
	pthread_mutex_unlock(&mutex);
}
void V(int* semaphore)
{
	pthread_mutex_lock(&mutex);
	*semaphore = *semaphore + 1;
	conditionMet = 1;
	if(*semaphore <= 0)	pthread_cond_signal(&condition);
	else			pthread_mutex_unlock(&mutex);
}

과제이오니 답을 바로 안 가르쳐주시더라도 해결할 실마리 부탁드립니다^^
이것만 6시간째 해결 못하고 있습니다.
미리 감사드립니다.
prether의 이미지

pthread_cond_wait(&condition, &mutex);
statement실행하기 전에
pthread_mutex_unlock(&mutex);
를 실행한 것이 잘 못되었다고 봅니다.

/***************************************
Being the one is just like being in love.
***************************************/

/***************************************
Being the one is just like being in love.
***************************************/

lootpiz의 이미지

I'm working on IT.

ㅜ.ㅜ

I'm working on IT.

그노카스의 이미지

자세히 살펴볼 심적, 물리적 시간이 부족해서요.

void V(int* semaphore)
{
	pthread_mutex_lock(&mutex);
	*semaphore = *semaphore + 1;
	conditionMet = 1;
	if(*semaphore <= 0)	pthread_cond_signal(&condition);
	else			pthread_mutex_unlock(&mutex);          // <-- 요기
}

"요기" 부분이 실행안되는 경우가 발생할 수 있을듯 한데요.
뮤텍스에선.. 큰일날 일이죠. ㅎㅎ

lootpiz의 이미지

I'm working on IT.
시간이 나시면 천천히 보아주세요.
그것만으로는 해결이 되지 않습니다.
그리고 알고리즘 상으로 else가 들어가는 것이 맞습니다.

I'm working on IT.

bushi의 이미지

답변하신 분들의 글을 다시 검토해보세요.
본인이 뭘 알고싶어하는지는 본인이 잘 알고있겠지만,
본인이 뭘 모르는지는 본인이 알기 힘듭니다.

반드시 lock 을 한 context 내에서 unlock 을 해야합니다.
다른 context 에서는 unlock 이 불가능합니다.

cond_signal() 측에서 lock 한 것을
cond_wait() 측에서 unlock 한다.

는 개념 자체를 수정하셔야 합니다.

OTL

댓글 달기

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