2012-10-22 20 views
5

Xin chào, Tôi mới làm quen với lập trình đa luồng. Tôi đang cố gắng tạo mã tạo ra một chuỗi THREAD1, sau khi nó đã làm điều gì đó, nó kích hoạt hai luồng khác, nói THREAD2 và THREAD3, rồi thoát ra.pthreads: một chuỗi kích hoạt các chủ đề khác

Tôi đã viết hai giải pháp khả thi.

1) Sử dụng các biến điều kiện (KHÔNG LÀM VIỆC: trong một số trường hợp tôi nhận được một bế tắc):

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; 
bool ready = false; 

void* trigger(void*); 
void* func1(void*); 
void* func2(void*); 

int main() 
{ 
    pthread_t thread1; 
    pthread_t thread2; 
    pthread_t thread3; 
    pthread_create(&thread1, 0, &trigger, 0); 
    pthread_create(&thread2, 0, &func1, 0); 
    pthread_create(&thread3, 0, &func2, 0); 
    pthread_join(thread1, 0); 
    pthread_join(thread2, 0); 
    pthread_join(thread3, 0); 
} 

void *trigger(void*) 
{ 
    pthread_mutex_lock(&ready_mutex); 
    ready = true; 
    pthread_cond_broadcast(&ready_cond); 
    pthread_mutex_unlock(&ready_mutex); 
    return 0; 
} 

void *func1(void*) 
{ 
    while (!ready) // Needed to avoid spuriuos wake-up 
    { 
     pthread_mutex_lock(&ready_mutex); 
     pthread_cond_wait(&ready_cond, &ready_mutex); 
     pthread_mutex_unlock(&ready_mutex); 
    } 
    std::cout << "In 'func1'>> Do something" << std::endl; 
    return 0; 
} 

void *func2(void*) 
{ 
    while (!ready) // Needed to avoid spuriuos wake-up 
    { 
     pthread_mutex_lock(&ready_mutex); 
     pthread_cond_wait(&ready_cond, &ready_mutex); 
     pthread_mutex_unlock(&ready_mutex); 
    } 
    std::cout << "In 'func2'>> Do something" << std::endl; 
    return 0; 
} 

2) thread1 trực tiếp tạo ra hai chủ đề khác.

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; 

pthread_t thread1; 
pthread_t thread2; 
pthread_t thread3; 

void* trigger(void*); 
void* func1(void*); 
void* func2(void*); 

int main() 
{ 
    pthread_create(&thread1, 0, &trigger, 0); 

    pthread_join(thread1, 0); 
    pthread_join(thread2, 0); 
    pthread_join(thread3, 0); 
} 

void *trigger(void*) 
{ 
    std::cout << "In 'trigger'>> Do something" << std::endl; 

    pthread_create(&thread2, 0, &func1, 0); 
    pthread_create(&thread3, 0, &func2, 0); 

    return 0; 
} 

void *func1(void*) 
{ 
    std::cout << "In 'func1'>> Do something" << std::endl; 

    return 0; 
} 

void *func2(void*) 
{ 
    std::cout << "In 'func2'>> Do something" << std::endl; 

    return 0; 
} 

tôi muốn biết ý kiến ​​của bạn. Thank you very much

+0

Triển khai thứ hai của bạn dường như hoạt động tốt, bạn nghĩ điều gì sai với nó? – engineerC

+0

Tùy chọn thứ hai của bạn sạch và đẹp hơn. Tôi sẽ làm điều đó. –

+0

@CaptainMurphy: Tôi tự hỏi nếu có cách nào tốt hơn để đạt được mục tiêu này. Từ trang hướng dẫn sử dụng POSIX, có vẻ như với tôi rằng các biến điều kiện phù hợp hơn với mục tiêu này vì chúng có thể được sử dụng để báo hiệu cho một sự kiện cụ thể. –

Trả lời

5

Sử dụng các biến điều kiện (KHÔNG LÀM VIỆC: trong một số trường hợp tôi nhận được một bế tắc):

Các mã không khóa mutex khi kiểm tra tình trạng chia sẻ biến số ready. Khi nó khóa các mutex ready có thể cũng đã thay đổi bởi thời gian đó, đây là lý do tại sao bạn thấy deadlocks.

Phiên bản đúng để chờ thay đổi trạng thái với một biến trạng thái được (kiểm tra lỗi bỏ qua):

pthread_mutex_lock(&ready_mutex); 
while(!ready) // Needed to avoid spuriuos wake-up 
    pthread_cond_wait(&ready_cond, &ready_mutex); 
// ready == true here 
pthread_mutex_unlock(&ready_mutex); 

Ở trên giả định rằng ready là bao giờ thay đổi chỉ khi mutex cùng được tổ chức.

+0

Vâng, bạn nói đúng. Vì vậy, quay trở lại câu hỏi của tôi, tôi có nên sử dụng biến điều kiện (giải pháp # 1) hoặc tạo chủ đề trì hoãn (giải pháp # 2) không? –

+1

@ seg.fault Tôi muốn sử dụng [dao cạo của Occam] (http://en.wikipedia.org/wiki/Occam's_razor): đưa ra nhiều giải pháp cho một vấn đề lựa chọn đơn giản hơn. –

Các vấn đề liên quan