2012-10-29 41 views
5

Có cách nào để chặn các tín hiệu nhất định và bỏ chặn các tín hiệu khác trong cùng một bộ không? Tôi chỉ không có vẻ để có được đầu của tôi xung quanh nó!Tín hiệu khối chủ đề posix và bỏ chặn

Một ví dụ

sigset_t set; 
sigemptyset(&set); 

sigaddset(&set, SIGUSR1); 
// Block signal SIGUSR1 in this thread 
pthread_sigmask(SIG_BLOCK, &set, NULL); 
sigaddset(&set, SIGALRM); 
// Listen to signal SIGUSR2 
pthread_sigmask(SIG_UNBLOCK, &set, NULL); 


pthread_t printer_thread1, printer_thread2; 
pthread_create(&printer_thread1, NULL, print, (void *)&f1); 
pthread_create(&printer_thread2, NULL, print, (void *)&f2); 

bool tl = true; 
while(1) 
{ 
    if(tl) 
    { 
     // thread1 does something 
     kill(pid, SIGUSR1); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
    else 
    { 
     // thread2 does something 
     kill(pid, SIGUSR2); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
} 

Tôi không được phép sử dụng Mutexs, Cột vv tín hiệu duy nhất.

Ai đó có thể trợ giúp? :)

+0

Bạn không phải là người đầu tiên chặn và sau đó bỏ chặn SIGUSR1 tại đây? Tại thời điểm UNBLOCK, tập hợp chứa cả SIGUSR1 và SIGALRM. – amaurea

Trả lời

9

Có cách nào để chặn một số tín hiệu nhất định và bỏ chặn các tín hiệu khác trong cùng một bộ không?

Với pthread_sigmask, bạn có thể chọn một trong hai:

  • thêm một tập hợp các tín hiệu với tập hợp các tín hiệu bị chặn, sử dụng hằng SIG_BLOCK
  • loại bỏ một tập hợp các tín hiệu đến bộ bị chặn tín hiệu, sử dụng hằng số SIG_UNBLOCK
  • xác định bộ tín hiệu bị chặn, sử dụng hằng số SIG_SET

Nói cách khác, có một tập hợp các tín hiệu bị chặn hiện tại cho chuỗi và bạn có thể sửa đổi nó như được chỉ định ở trên, một thao tác tại một thời điểm.

Điểm quan trọng là chủ đề mới tạo kế thừa mặt nạ tín hiệu của chuỗi tạo, vì vậy bạn có thể đặt mặt nạ của chuỗi mới ngay trước khi tạo chuỗi hoặc trong chức năng mà chuỗi mới sẽ chạy, thuận tiện cho bạn .

Về ví dụ của bạn, tôi giả sử rằng bạn đang cố gắng để có printer_thread1 khối SIGUSR2SIGALRM, và có printer_thread2 khối SIGUSR1SIGALRM, và có khối chủ đề chính SIGUSR1SIGUSR2, để mỗi chủ đề có thể gửi một tín hiệu rằng sẽ bị bắt bởi một sợi đơn (không có mã số print, f1f2, bạn không thể biết chắc chắn ý định của mình trong ví dụ của bạn là gì).

Bạn sẽ có thể đạt được điều đó bằng đoạn mã sau:

sigset_t set; 
pthread_t printer_thread1, printer_thread2; 


// Block signal SIGUSR1 & SIGALRM in printer_thread1 
sigemptyset(&set); 
sigaddset(&set, SIGUSR1); 
sigaddset(&set, SIGALRM); 
pthread_sigmask(SIG_SET, &set, NULL); 
pthread_create(&printer_thread1, NULL, print, (void *)&f1); 

// Block signal SIGUSR2 & SIGALRM in printer_thread2 
sigaddset(&set, SIGUSR2); 
sigaddset(&set, SIGALRM); 
pthread_sigmask(SIG_SET, &set, NULL); 
pthread_create(&printer_thread2, NULL, print, (void *)&f2); 

// Block signal SIGUSR1 & SIGUSR2 in the main thread 
sigemptyset(&set); 
sigaddset(&set, SIGUSR1); 
sigaddset(&set, SIGUSR2); 
// Listen to signal SIGALRM 
pthread_sigmask(SIG_SET, &set, NULL); 


bool tl = true; 
while(1) 
{ 
    if(tl) 
    { 
     // thread1 does something 
     kill(pid, SIGUSR1); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
    else 
    { 
     // thread2 does something 
     kill(pid, SIGUSR2); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
} 

nhìn thấy những người đàn ông trang:

để biết thêm chi tiết.

+0

Cảm ơn, điều này có ý nghĩa, nhưng nó thực sự không hoạt động với các chủ đề máy in. Nhưng tôi hiểu làm thế nào mặt nạ làm việc ngay bây giờ. – Max

1

Tôi nghĩ rằng những gì bạn muốn làm ở đây là

// Block signal SIGUSR1 in this thread 
sigemptyset(&set); 
sigaddset(&set, SIGUSR1); 
pthread_sigmask(SIG_BLOCK, &set, NULL); 

// Listen to signal SIGALRM 
sigemptyset(&set); 
sigaddset(&set, SIGALRM); 
pthread_sigmask(SIG_UNBLOCK, &set, NULL); 

Tập chỉ được dùng để nói với nó những gì để chặn hoặc mở khóa. Sau khi được thông qua lệnh, bạn có thể tự do thiết lập lại và xây dựng một mặt nạ tín hiệu khác. Nếu bạn bỏ qua sigemptyset, tập hợp sẽ vẫn chứa SIGUSR1, và nó sẽ được bỏ chặn lần nữa. Vâng, tôi nghĩ đó là cách nó hoạt động, ít nhất - nó đã được một thời gian dài kể từ khi tôi sử dụng tín hiệu.

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