2017-12-20 29 views
0

메인 스레드없이 다른 모든 pthread를 멈출 수있는 프로그램을 작성하고 싶습니다. pthread_kill을 사용하여 신호 처리기를 호출하여 블럭을 호출 할 수 있습니다 그 자체. 그러나 나는 붙어있어. 여기에 코드 아래의 (?이 사실이다)Pthread는 블럭 안의 pthread_cond_wait를 사용하여 블럭을 닫습니다.

#include <iostream> 
#include <signal.h> 
#include <pthread.h> 
#include <unistd.h> 
#include <cassert> 

using namespace std; 

pthread_mutex_t _mutex; 
pthread_cond_t cond; 

void cur_thread_wait(int sig) 
{ 
    cout << pthread_self() << endl; 

// pthread_mutex_lock(&_mutex); 
    pthread_cond_wait(&cond, &_mutex); 
// pthread_mutex_unlock(&_mutex); 
} 

void signal_all() 
{ 
    pthread_cond_broadcast(&cond); 
} 

void *print(void *) 
{ 
    pthread_detach(pthread_self()); 
    for (int i = 0; i < 100; i ++) { 
     cout << dec << i << endl; 
    } 
    return nullptr; 
} 


int main(int argc, char *argv[]) 
{ 
    pthread_mutex_init(&_mutex, nullptr); 
    pthread_cond_init(&cond, nullptr); 

    signal(SIGUSR1, cur_thread_wait); 

    pthread_t pid1, pid2, pid3; 
    pthread_create(&pid1, nullptr, print, nullptr); 
    pthread_create(&pid2, nullptr, print, nullptr); 
    pthread_create(&pid3, nullptr, print, nullptr); 

// usleep(400); 

    pthread_kill(pid1, SIGUSR1); 
    pthread_kill(pid2, SIGUSR1); 
    pthread_kill(pid3, SIGUSR1); 

    signal_all(); 


    pthread_exit(nullptr); 
} 

는 사실, 나는 mutex을 만들 필요가 정말 없다 생각 ... 나는 리눅스 프로그래밍에 초보자입니다. 이 문제를 어떻게 해결할 수 있습니까? 고맙습니다.

+0

이것은 깨졌습니다. 신호 처리기에서 차단해서는 안됩니다! –

답변

1

pthread_cond_wait을 호출하기 전에 뮤텍스를 잠글 필요가 있습니다. 그것은 잠길 것으로 예상하고, 잠금을 해제하고, 조건 변수가 선언 될 때까지 대기 한 다음, 다시 복귀하기 전에 다시 잠급니다. pthread_cond_wait(3p) 가입일

:

int pthread_cond_wait(pthread_cond_t *restrict cond, 
    pthread_mutex_t *restrict mutex); 

pthread_cond_timedwait()pthread_cond_wait() 함수 조건 변수에 차단한다. 응용 프로그램은 호출 스레드가 뮤텍스을 사용하여 이러한 함수를 잠그도록해야합니다. 그렇지 않으면 오류 (PTHREAD_MUTEX_ERRORCHECK 및 강력한 뮤텍스의 경우) 또는 정의되지 않은 동작 (다른 뮤텍스의 경우)이 발생합니다.

+0

감사합니다. 나는 내 잘못을 발견한다. 만약'signal_all' 바로 전에'usleep '을 넣으면 프로그램이 올바르게 진행된다. 게다가 뮤텍스가 필요하기 때문에 당신 말이 맞습니다. – wind2412

+0

업데이트 해 주셔서 감사합니다! 대부분의 시스템 (리눅스 포함)에서'sched_yield'를 사용할 수도 있습니다. –

+0

그는 신호 처리기에서 블로킹 호출을해서는 안됩니다. 또한, 질문이 C++로 표시되기 때문에 posix 스레드를 죽이고 취소하면 C++에서 문제를 일으킬 수 있습니다. 예 : https://skaark.wordpress.com/2010/08/26/pthread_cancel-considered-harmful/ –