2010-09-28 8 views
10

Đây là một kịch bản khá cơ bản nhưng tôi không tìm thấy quá nhiều tài nguyên hữu ích. Tôi có một chương trình C++ chạy trong Linux mà không xử lý tập tin. Đọc các dòng, thực hiện các phép chuyển đổi khác nhau, ghi dữ liệu vào cơ sở dữ liệu. Có một số biến nhất định (được lưu trữ trong cơ sở dữ liệu) ảnh hưởng đến quá trình xử lý mà tôi hiện đang đọc ở mỗi lần lặp vì tôi muốn xử lý được cập nhật nhất có thể, nhưng độ trễ nhỏ là OK. Nhưng những biến đó thay đổi khá hiếm khi, và số lần đọc rất tốn kém theo thời gian (10 triệu hàng cộng thêm một ngày). Tôi có thể giải phóng các lần đọc cho mỗi lần lặp lại n hoặc đơn giản là khởi động lại chương trình khi biến thay đổi, nhưng những biến đó dường như bị hack.Xử lý tín hiệu cơ bản trong C++

Điều tôi muốn làm thay vào đó là chương trình kích hoạt đọc lại các biến khi nhận được SIGHUP. Tất cả mọi thứ tôi đọc về xử lý tín hiệu đang nói về thư viện tín hiệu C mà tôi không chắc chắn làm thế nào để buộc vào các lớp học của chương trình của tôi. Các thư viện tín hiệu Boost dường như được nhiều hơn về giao tiếp giữa các đối tượng hơn là xử lý các tín hiệu OS.

Ai đó có thể trợ giúp? Nó có vẻ như thế này là vô cùng đơn giản, nhưng tôi khá gỉ với C++.

Trả lời

15

Tôi sẽ xử lý nó giống như bạn có thể xử lý nó trong C. Tôi nghĩ rằng nó hoàn toàn tốt để có một chức năng xử lý tín hiệu độc lập, vì bạn sẽ chỉ được đăng lên semaphore hoặc thiết lập một biến hoặc một số như vậy, mà một chủ đề hoặc đối tượng khác có thể kiểm tra để xác định xem nó có cần đọc lại các cài đặt hay không.

#include <signal.h> 
#include <stdio.h> 

/* or you might use a semaphore to notify a waiting thread */ 
static volatile sig_atomic_t sig_caught = 0; 

void handle_sighup(int signum) 
{ 
    /* in case we registered this handler for multiple signals */ 
    if (signum == SIGHUP) { 
     sig_caught = 1; 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    /* you may also prefer sigaction() instead of signal() */ 
    signal(SIGHUP, handle_sighup); 

    while(1) { 
     if (sig_caught) { 
      sig_caught = 0; 
      printf("caught a SIGHUP. I should re-read settings.\n"); 
     } 
    } 

    return 0; 
} 

Bạn có thể thử gửi SIGHUP bằng cách sử dụng kill -1 `pidof yourapp`.

+1

Oh duh. Tôi đã hoàn toàn overthinking nó và quên rằng các biến tín hiệu là những gì tôi muốn chứ không phải là invocation trực tiếp. * headdesk * – KernelM

+4

Nếu bạn muốn tuân thủ các tiêu chuẩn, hãy đảm bảo đủ điều kiện trình xử lý tín hiệu của bạn là 'extern' C '' –

+0

@R Samuel: Đó là một điểm tuyệt vời.Tôi thậm chí còn không nghĩ về 'extern' C ''vì tôi đang viết mã C, nhưng OP sẽ cần nó! –

1

Có một số khả năng; nó sẽ không nhất thiết phải quá mức để triển khai tất cả chúng:

  • Trả lời một tín hiệu cụ thể, giống như C. C++ hoạt động theo cùng một cách. Xem tài liệu cho signal().
  • Kích hoạt trên dấu thời gian sửa đổi của một số tệp thay đổi, như cơ sở dữ liệu nếu tệp được lưu trữ trong tệp phẳng.
  • Kích hoạt một lần mỗi giờ hoặc một lần mỗi ngày (bất kỳ điều gì có ý nghĩa).
3

Tôi khuyên bạn nên kiểm tra this link cung cấp thông tin chi tiết về cách đăng ký tín hiệu. Trừ khi tôi bị nhầm lẫn, một điều quan trọng cần nhớ là bất kỳ hàm nào bên trong một đối tượng đều mong đợi tham số tham chiếu, có nghĩa là các hàm thành viên không tĩnh không thể là trình xử lý tín hiệu. Tôi tin rằng bạn sẽ cần phải đăng ký nó hoặc là một chức năng thành viên tĩnh, hoặc một số chức năng toàn cầu. Từ đó, nếu bạn có một hàm đối tượng cụ thể mà bạn muốn quản lý bản cập nhật của mình, bạn sẽ cần một cách để tham khảo đối tượng đó.

+0

Trang web đó trông có vẻ bị đóng, vì vậy bạn có thể muốn xem [liên kết này] (http://www.yolinux.com/TUTORIALS/C++Signals.html) để biết chi tiết. –

+0

Không, cplusplus.com (và liên kết đó) vẫn có vẻ tốt cho tôi. Luôn luôn tốt để có nhiều tài liệu tham khảo mặc dù. – Bryan

0

Bạn có thể xác định tín hiệu Tăng tương ứng với tín hiệu OS và buộc tín hiệu Tăng vào khe của bạn để gọi trình xử lý tương ứng.