2011-11-11 47 views
9

Tôi có một ứng dụng chính để sinh ra một luồng riêng biệt để xử lý các tin nhắn từ một hàng đợi. Tôi có một vấn đề trên AIX khi tôi nhấn CTRL-C vì nó dường như làm cho một số "xử lý kết nối" trong thread trở thành không hợp lệ. Tôi có một móc tắt máy trong chương trình chính bắt SIGINT nhưng trên AIX nó dường như bằng cách nào đó gửi một tín hiệu cho các sợi cũng ... mặc dù đó là không thực sự có thể từ những gì tôi nghe ...Làm thế nào để chặn tất cả TÍN HIỆU trong chuỗi KHÔNG sử dụng SIGWAIT?

Về cơ bản tôi muốn biết liệu tôi có muốn ứng dụng CHÍNH xử lý TẤT CẢ các tín hiệu mà tôi quan tâm và có/không BAO GIỜ xử lý bất kỳ tín hiệu nào ... đó có phải là "thực hành tốt" không?

Nếu vậy làm thế nào tôi không thể sử dụng "sigwait" trong chủ đề ... trên thực tế tôi không muốn bất kỳ "mã tín hiệu" trong thread/s ... họ chỉ đơn giản là không nhận được bất kỳ tín hiệu nào cả.

Tôi đã làm trống ra tất cả các tín hiệu:

sigemptyset(&set); 

Và đã thiết lập các SIG_BLOCK

s = pthread_sigmask(SIG_BLOCK, &set, NULL); 

Vì vậy, đây là một thử nghiệm programe giả:

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <signal.h> 
#include <errno.h> 

#define handle_error_en(en, msg) do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) 

static void * threadMainLoop(){ 
    //Here I do not want the thread to use "sigwait".... 
    while(running == TRUE){ 
     //do some thread work and never have any signals come in 
    } 
} 

void shutdownHook(int sig){ 
    printf("\nCtrl-C pressed....shutdown hook in main...\n"); 
} 

void signalErrorHandler(int signum){ 
    printf("\nSignal error handler in main...\n"); 
} 

int main(int argc, char *argv[]){ 
    pthread_t thread; 
    sigset_t set; 
    int s; 

    //Catch the following signals in the MAIN thread 
    (void) signal(SIGINT, shutdownHook); 
    (void) signal(SIGSEGV, signalErrorHandler); 
    (void) signal(SIGBUS, signalErrorHandler); 
    (void) signal(SIGILL, signalErrorHandler); 
    (void) signal(SIGTERM, signalErrorHandler); 
    (void) signal(SIGABRT, signalErrorHandler); 

    sigemptyset(&set); //BLOCK all signals 

    s = pthread_sigmask(SIG_BLOCK, &set, NULL); 
    if (s != 0) 
     handle_error_en(s, "pthread_sigmask"); 

    s = pthread_create(&thread, NULL, &threadMainLoop, (void *) NULL); 
    if (s != 0) 
     handle_error_en(s, "pthread_create"); 

    pause(); 
} 

Nếu tôi chỉ cần tạo một chuỗi và có, ví dụ, bộ xử lý tín hiệu SIGINT trong chuỗi MAIN nhưng KHÔNG có bộ SIG_BLOCK cho thre quảng cáo và người dùng truy cập CTRL-C .... hiện các chủ đề bị ảnh hưởng ở tất cả mặc dù xử lý tín hiệu trong thread chính chạy? Đó dường như những gì tôi đang nhìn thấy trên AIX ;-(

Thanks for the help, nhiều đánh giá cao

Lynton

Trả lời

13

Với s = pthread_sigmask(SIG_BLOCK, &set, NULL);, bạn không chặn bất cứ điều gì

Sử dụng:.

sigfillset(&set); 
sets = pthread_sigmask(SIG_SETMASK, &set, NULL); 

Nếu bạn muốn chặn mọi tín hiệu hoặc thêm rõ ràng các tín hiệu bạn muốn chặn vào set nếu bạn đang sử dụng SIG_BLOC K.

Sau khi bạn đã tạo chủ đề, bạn cần khôi phục mặt nạ tín hiệu, nếu không luồng sẽ không nhận bất kỳ tín hiệu nào.

Tuy nhiên, nhìn vào câu hỏi trước của bạn, có thể là chuỗi bắt tín hiệu không xử lý bị gián đoạn. Đó là, nếu bạn bị chặn làm một syscall, và một tín hiệu đến, syscall đó bị hủy bỏ. Một số hệ điều hành mặc định tự động gọi lại cuộc gọi hệ thống, một số trả về lỗi và đặt errno thành EINTR, ứng dụng phải xử lý - và những điều xấu có thể xảy ra nếu không được xử lý. Thay vào đó, hãy cài đặt trình xử lý tín hiệu của bạn với sigaction() thay vì tín hiệu() và đặt cờ SA_RESTART, điều này sẽ làm cho các cuộc gọi hệ thống tự động khởi động lại trong trường hợp tín hiệu bị hủy bỏ bởi tín hiệu.

+0

Xin chào, nhưng tôi đặt "s = pthread_sigmask (SIG_BLOCK, & set, NULL);" và thử nghiệm với CTRL-C mà thread không nhận được tín hiệu? Điều đó có nghĩa là nó đang chặn nó? Nếu tôi thêm "sigaddset (& set, SIGINT);" sau đó luồng nhận tín hiệu. Hãy tha thứ cho tôi nếu tôi sai ở đây ... Tôi vẫn đang học .. ;-) Cảm ơn sự giúp đỡ ;-) –

+0

Cập nhật câu trả lời một chút .. Mặt nạ tín hiệu là tín hiệu không thể nâng lên. Vì vậy, nếu bạn làm sigaddset (& set, SIGINT); pthread_sigmask (SIG_BLOCK, & set, NULL); , SIGINT sẽ được đặt trong mặt nạ singnal, và điều đó có nghĩa là luồng sẽ không nhận được nó. Nếu bạn tạo một luồng mới, luồng đó sẽ thừa hưởng mặt nạ tín hiệu từ chuỗi đã tạo ra nó. – nos

+0

Lưu ý rằng nếu bạn muốn một luồng mới bắt đầu với các dấu hiệu bị che dấu (thường cần thiết để tránh các điều kiện khó chịu), bạn cần chặn các tín hiệu trước khi gọi 'pthread_create' và sau đó khôi phục mặt nạ tín hiệu cũ trong chuỗi ban đầu sau khi' pthread_create' trả về . –

-11

Thiết kế sai. Không sử dụng CTRL + C để dừng ứng dụng theo cách được kiểm soát. Sử dụng ứng dụng bộ điều khiển được thiết kế chính xác có thể truy cập được qua CORBA, RMI hoặc một số phương pháp khác để tương tác với người dùng và kiểm soát ứng dụng nền.

Chúc các bạn vui vẻ ...

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