2009-05-27 46 views
6

Tôi đang viết một chương trình, với một chuỗi chủ và một số chuỗi công việc, và tôi muốn nhận được quyền xử lý tín hiệu. Vấn đề của tôi là như sau:luồng chủ/công nhân và xử lý tín hiệu

bắt đầu Thầy chủ đề và làm tất cả việc phân bổ

Thạc sĩ đề đặt ra một xử lý tín hiệu SIGINT

đề Thạc sĩ bắt đầu đề người lao động. công nhân chủ đề không cần dọn dẹp đặc biệt, tuy nhiên họ có thể ngủ trên hệ thống gọi hoặc semaphore.

Khi nhận được SIGINT, sự hiểu biết của tôi là chỉ có một luồng nhận được. Vì vậy, nếu thread đang ngủ trên hệ thống gọi hoặc semaphore, họ sẽ không được waked lên, và tôi sẽ không thể pthread_join chủ đề công nhân của tôi và làm tất cả các dọn dẹp cần thiết trong chủ đề của tôi.

Trình xử lý tín hiệu sau có thể giải quyết được sự cố của tôi không?

void term(int sig) 
{ 
    g_do_cleanup = 1; 
    pthread_kill(worker_1_id, some_other_signal); 
    ... 
    pthread_kill(worker_2_id, some_other_signal); 
} 

Những gì tôi mong đợi là khi nhận SIGINT, tất cả các chủ đề sẽ được báo hiệu bằng tín hiệu khác, thoát khỏi cuộc gọi chặn của họ, xem g_do_cleanup cờ và thoát một cách duyên dáng.

Bất kỳ nhận xét hoặc liên kết nào về cách thực hiện việc này đều được hoan nghênh.

Chỉnh sửa: Tôi không tìm cách đánh thức nhiều chuỗi đang đợi trên một điều kiện cụ thể, vì vậy tôi không nghĩ rằng phương pháp pthread_cond_signal là những gì tôi đang tìm kiếm. Những gì tôi muốn là:

  • Tìm một cách mà tất cả các chủ đề đó là chặn trên một cuộc gọi chặn trả từ các cuộc gọi.
  • Hoặc tiêu diệt tất cả các chủ đề ngoại trừ chủ đề chính.

Trả lời

4

Đây là những gì tôi thường làm trong các chủ đề ứng dụng chính:


/* before starting other threads */ 
sigset_t sigs; 
sigemptyset(&sigs); 
sigaddset(&sigs, SIGTERM); 
sigaddset(&sigs, SIGINT); 
/* add other signals to handle */ 
if (pthread_sigmask(SIG_BLOCK, &sigs, 0)) { /* handle error */ } 
/* can start threads now */ 
... 
/* in the main event loop */ 
siginfo_t info; 
if (sigwaitinfo(&sigs, &info) == -1) { /* handle error */ } 
switch(info.si_signo) 
{ 
    case SIGTERM: 
    case SIGINT: /* raise shutdown event */ break; 
    default: /* other actions - log rotation, etc. */ 
} 
... 

Bằng cách này các tín hiệu trở thành sự kiện ứng dụng bình thường - không có hạn chế bối cảnh tín hiệu đặc biệt, vv Chờ đợi cũng có thể được thực hiện với một thời gian chờ qua sigtimedwait , mặc dù các dẫn xuất BSD không hỗ trợ nó.

2

Nghe có vẻ giống như những gì bạn muốn là biến điều kiện pthread, để bạn có thể đánh thức bất kỳ số lượng chủ đề nào bằng cách hát một "sự kiện" từ chuỗi chủ của bạn.

Xem trang hướng dẫn sử dụng cho PTHREAD_COND_DESTROYPTHREAD_COND_BROADCAST để biết thêm thông tin.

+0

Vâng.Hầu hết mọi người sử dụng pthread hoặc Win32/MFC triển khai để làm chủ đề – Kieveli

+0

Không, tôi không nghĩ rằng nó là ok, bởi vì nó sẽ không đánh thức tôi dậy từ một cuộc gọi chọn chặn, hoặc một cuộc gọi sem_wait. Có lẽ tôi có thể thay thế các semaphores bằng một pthread_condition, nhưng sự trừu tượng semaphore thực sự phù hợp với mô hình đồng bộ hóa của tôi. – shodanex

1

Kế hoạch của bạn có vẻ ổn. Bạn đang buộc một luồng để xử lý tín hiệu hệ thống. Bạn sẽ cần phải che dấu các tín hiệu ngoại trừ một số tín hiệu khác trong luồng công nhân của bạn với pthread-sigmask().

Tôi nghĩ rằng tôi sẽ đi với một sợi riêng biệt để xử lý tín hiệu quá trình chứ không phải là chính. Có nó chờ đợi mãi mãi trên một semaphore hoặc sigwait() hoặc bất cứ điều gì trong khi chờ đợi để chạy xử lý tín hiệu. Di chuyển mã pthread-kill ra khỏi bộ xử lý tín hiệu. Chỉ cần đặt công tắc và có chuỗi chờ tín hiệu gửi another_signal tới các chuỗi công nhân và tự thoát.

+0

Sử dụng tín hiệu để giao tiếp giữa các luồng là cách tiếp cận sai. nhiều thư viện luồng thậm chí không hoạt động với các tín hiệu. Nó tốt hơn nhiều để sử dụng các cơ chế đồng bộ tread được cung cấp bởi thư viện luồng như các biến điều kiện được đề cập. – lothar

+0

Tín hiệu là nguyên thủy và xa lý tưởng nhưng thư viện của ông rõ ràng hỗ trợ họ hoặc ông sẽ không được yêu cầu. Anh ấy không làm bất cứ điều gì đã không được thực hiện thành công nhiều lần. – Duck

+0

Điều này không phải như vậy về giao tiếp thread, nhưng về chấm dứt thread. pthread_cancel + chuỗi xử lý tín hiệu có thể hoạt động – shodanex

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