2012-12-05 3 views
2

모두. 나는 세마포어를 처음 사용하고 있으며 최근에는 바이너리 세마포어를 사용하여 간단한 문제를 구현하는 방법을 배우고 있으며 몇 가지 질문이 있습니다.바이너리 세마포어를 사용하여 C++에서 스레드를 동기화하십시오.

방문 방이 있습니다. 한 번에 한 사람 만 들어갈 수 있습니다. 내 디자인에는 3 개의 대기열 (모든 스레드가 있습니다)이 있습니다. 예를 들어, 두 번째 대기열에있는 사람이 그 방을 방문한 후 방에 들어가는 다음 사람은 첫 번째 대기열의 사람이 아니라 세 번째 대기열에서 대기중인 사람입니다. 총 인원수가 주어집니다. 떠난 후에 스레드를 종료하면됩니다.

두 번째 대기열에있는 한 사람이 들어간 다음 세 번째 대기열을 차단하고 계속해서 세 번째 대기열에 "신호"만 보내면 세 개의 세마포를 만들려고합니다. 등등. 그러나 코드에는 몇 가지 문제점이 있습니다. 여기서는 코드의 일부 세마포어 부분을 보여줍니다. 메인 INT

:

sem_init (& 뮤텍스, 0, 1);

sem_init (&s0, 0, 1);

sem_init (&s1, 0, 1);

sem_init (& s2, 0, 1);

// 100의 pthread를 생성하고 무작위로 스레드 함수에서 queue0 또는 queue1을 또는 queue2

for(int i = 0; i<num_thread; i++){ 

     pthread_t curr_thread; 
     if(queueId == 0){ 
      queue0.push(curr_thread);   
     }else if(queueId == 1){ 
      queue1.push(curr_thread); 
     }else if(queueId == 2){ 
      queue2.push(curr_thread); 
     } 
      pthread_attr_t attr; 
      pthread_attr_init (&attr); 
      pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); 
      pthread_create (&curr_thread, &attr, &thread_function, &queue_Num); 
      pthread_attr_destroy (&attr); 

    } 

에 넣어 : 나는 그것을 실행할 때 나는 "교착 상태"를 만난 것처럼

void* thread_function (void* arg){ 

     sem_wait(&mutex); 

     int n = *((int*) arg); 
     if(n==0){ 
      sem_wait(&s0); 
      cout << "person in queue" << n << " is visiting" << endl; 
      sleep(1); 
      if(!queue0.empty()){ 
       queue0.pop(); 
      }else{ 
       n++; 
      } 
      sem_post(&s1); 

     }else if(n==1){ 
      sem_wait(&s1); 
      cout << "person in queue" << n << " is visiting" << endl; 
      sleep(1); 
      if(!queue1.empty()){ 
       queue1.pop(); 
      }else{ 
       n++; 
      } 
      sem_post(&s2); 
     }else if(n==2){ 
      sem_wait(&s2); 
      cout << "person in queue" << n << " is visiting" << endl; 
      sleep(1); 
      if(!queue2.empty()){ 
       queue2.pop(); 
      }else{ 
       n++; 
      } 
      sem_post(&s0); 
     } 

     sem_post(&mutex); 

    return NULL; 
} 

가 실제로 보인다 , 메인은 매회 2 개의 스레드 만 보여 주기만하면됩니다. thread_function 디자인에 몇 가지 문제가 있어야한다고 생각했습니다. 아무도 그것을 지적하고 그것을 해결하는 방법을 말해 줄 수 있습니까? 고맙습니다.

+0

기다리기 전에 print 문을 두어보고 내게 무엇이 있는지 말해보십시오. – Xymostech

+0

단순히 차단하여 하나의 스레드가 방문 중임을 표시 한 다음 주 스레드가 완료되었음을 나타냅니다. 나는 thread_function의 디자인에 문제가 있는지 궁금하다. – user1878173

+0

'queueId'와'queue_Num'은 어떻게 정의되어 있습니까? – Xymostech

답변

0

queueId을 스레드에 전달할 때 매우 빠르게 변경하려고하기 때문에 로컬 변수 중 하나에 포인터를 전달하지 않으려합니다. 당신 대신 당신의 스레드 정수 자체를 전달해야합니다

void* thread_function (void* arg){ 
    ... 

    int n = (long)arg; 

    .. 
} 

:

pthread_create(&curr_thread, &attr, &thread_function, (void*)queueId); 
             // Pass queueId the int, not a pointer 

를 그리고, 당신이 당신의 스레드에서 값을 읽을 필요가있을 때, 단지 정수로 다시 void* 캐스팅 이 후, 당신의 코드는 훌륭하게 작동합니다.

+0

결과는 "person1이 (가) 방문 중임"을 표시 한 다음 프로그램이 완료되었습니다 ... 다른 스레드의 상태는 무엇입니까? 나는 테스트를 위해 10 개의 스레드를 만들었고 어떤 사람이 들어가는 지 10 회 알려주거나 .. 당신의 연락처를 남겨 둘 수 있습니까, 아마도 이메일 주소, 나는 당신에게 코드를 보낼 수 있습니다. – user1878173

관련 문제