[완료]쓰레드를 이용한 통신 프로그램에서 mutex, cond 문제

neohwang의 이미지


쓰레드를 이용한 통신프로그램입니다.

SocketRead() 함수에서 ThreadRead 함수로 mutex와 cond_signal을 이용하여 넘기는 구조입니다.

문제는 rIdx 값을 이용하여 변수를 넘기는 부분인데요.

1. SocketRead()함수에서 rPool[rIdx++] 해서 변수값을 넘깁니다.

2. ThreadRead에서 rIdx가 0이면 cond_wait로 시그날을 기다립니다.

문제는 위 2번에서 절대로 rIdx가 0이면 그 아래 printf()문을 수행할수 없을 것 같은데..
수행이 되네요..

이 부분이 왜 그런지 도움 부탁드립니다.

감사합니다.

// Read 처리
pthread_t	rTid[MAX_THREAD_R];
pthread_mutex_t	rmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t	rcond = PTHREAD_COND_INITIALIZER;
struct SESSIONS *rPool[MAX_POOL];	// session을 쓰레드로 전달하기 위한 임시 저장소
int rIdx = 0;
 
 
int SocketRead(struct SESSIONS *session, time_t tick)
{
	pthread_mutex_lock(&rmutex);
	rPool[rIdx++] = session;
	pthread_cond_signal(&rcond);   // 시그날이 보내질때는 항상 rIdx가 1 이상이 됩니다.
	pthread_mutex_unlock(&rmutex);
	return 1;
}
 
void *ThreadRead(void *param)
{
	struct SESSIONS *session;
	while(1)
	{
		//---------------------------------
		// Read Mutex Lock & Wait & Unlock
		//---------------------------------
		pthread_mutex_lock(&rmutex);
		if(rIdx == 0)	pthread_cond_wait(&rcond, &rmutex);
printf("R rrr critical  %d\n", rIdx);			// R rrr critical  0 <-- 여기가 문제.. 왜 0이 찍히는지... ㅠㅠ
		session = rPool[--rIdx];
		pthread_mutex_unlock(&rmutex);
		//---------------------------------
jick의 이미지

pthread_cond_signal은 하나 이상의 기다리는 쓰레드를 깨울 수 있습니다. 그리고 그 문제가 아니더라도 pthread_cond_wait에서 시그널을 받고 깨어나려는 순간 다른 쓰레드가 새치기를 해서 rIdx를 감소시킬 수 있지요.

if (rIdx == 0)을 while (rIdx == 0)으로 바꾸면 될 것 같네요.

neohwang의 이미지

우선 답변 정말 고맙습니다. ^^

그런데.. 답변중에..

"pthread_cond_signal은 하나 이상의 기다리는 쓰레드를 깨울 수 있습니다."

라고 하셨는데.. 이 부분이 맞는지요?

제가 알기로는

"여러개의 쓰레드가 기다리고 있다면 그중 하나의 쓰레드에게만 전달된다. 이때 어떤 쓰레드에게 신호가 전달될지는 알수 없다."

이렇게 알고있었는데요.. 다시 한번 도움 부탁드립니다.

dormael의 이미지

저도 궁금해서 찾아 보았는데

The pthread_cond_broadcast() function shall unblock all threads currently blocked on the specified condition variable cond.

The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).

적어도 하나라고 메뉴얼 페이지에 명시되어 있네요.

http://linux.die.net/man/3/pthread_cond_signal

-- Signature --
青い空大好き。
蒼井ソラもっと好き。
파란 하늘 너무 좋아.
아오이 소라 더좋아.

neohwang의 이미지

"at least one of the threads"

이 부분이 정확히 와닫지 않네요...

하나 이상이라는 뜻이 내포되는 것 같은데요..
그러면 pthread_cond_broadcast() 함수는 왜 있는지?

좀 더 명확하게 알려주세요.. ㅠㅠ

bushi의 이미지

if (rIdx == 0)	do { pthread_cond_wait(&rcond, &rmutex); } while (rIdx == 0);

OTL
neohwang의 이미지

while(rIdx == 0) pthread_cond_wait(&rcond, &rmutex);

와 같은 것 같은데요.. 답변 감사합니다.^^

댓글 달기

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