2011-08-01 39 views
5

chức năng gì trong C++ được đảm bảo để được gọi trong chấm dứt đột ngột hoặc lối ra mà có thể thực hiện các hoạt động dọn dẹp ..Chức năng đảm bảo để được gọi trong C++ trong chấm dứt đột ngột hoặc thoát

+6

về mặt kỹ thuật không có gì * được bảo đảm * - nếu bạn không có UPS và nguồn điện bị mất hoặc bộ nguồn của bộ xử lý không thành công hoặc bộ dao động xung nhịp (tất cả đều không thường xuyên nhưng có thể xảy ra) thì CPU sẽ ngừng hoạt động. –

Trả lời

2

Đọc về atexithere. Tuy nhiên, nó sẽ không được gọi trong tất cả các trường hợp (ví dụ: gọi abort sẽ không kích hoạt chức năng bạn đã đăng ký với atexit).

Bạn có thể thực hiện trình xử lý tín hiệu của riêng mình, sau đó tất cả các tín hiệu sẽ chuyển đến đó và bạn có thể làm bất cứ điều gì cho mỗi người trong số họ.

+0

Điều này càng gần với những gì mà OP yêu cầu như một người có thể nhận được. Không có gì đảm bảo rằng các trình xử lý thoát sẽ được gọi. Chương trình có thể kích hoạt tín hiệu không thể bị bắt hoặc không bị bắt; lập trình viên có thể gọi 'abort()' để buộc chương trình thoát ra bất thường hoặc '_Exit()' để buộc chương trình thoát ra bình thường nhưng để bỏ qua các trình xử lý thoát. Tuy nhiên, một trở về từ chính hoặc một cuộc gọi đến 'exit()' sẽ chạy các trình xử lý thoát. –

0

Bạn đang làm việc trong môi trường nào? bởi đột ngột bạn có nghĩa là Ctrl + C hoặc giết tín hiệu -9? Trên unix/linux, bạn có thể che dấu một số tín hiệu và cung cấp các trình xử lý, nhưng theo như tôi biết, bạn không thể che dấu tất cả tín hiệu (9 là một ví dụ về tín hiệu không thể che dấu được))

Một số thậm chí ở mức độ thấp hơn về hoạt động của hệ điều hành có thể có sẵn, nhưng tôi không quen thuộc với điều đó.

1

Bạn đang tìm kiếm set_terminate().

http://www.cplusplus.com/reference/std/exception/set_terminate/

Có chức năng tương tự khác trong cùng một tiêu đề, đó là có thể sử dụng cho các kịch bản bổ sung.

+0

Điều này gây ra sự chấm dứt đột ngột, không được gọi. – littleadv

+0

-1; đây không phải là những gì OP đã yêu cầu. –

+0

@littleadv Vâng chắc chắn :-D –

1
int main() 
{ 
    try 
    { 
     // all your code here 
    } 
    catch(...) 
    { 
     // cleanup 
    } 
    return 0; 
} 
+0

Rõ ràng là không, vì các tài liệu cho trạng thái set_terminate rằng "Một hàm xử lý chấm dứt là một hàm tự động được gọi khi quá trình xử lý ngoại lệ phải bị hủy bỏ vì một lý do nào đó." –

+0

Điều này không bao gồm tất cả mọi thứ, nhưng nó vẫn là một đường cơ sở tốt. – zwol

0

Tôi không phải là một chuyên gia và tôi chỉ biết một số vài điều về C++, nhưng tôi biết bạn có thể tạo xử lý trong Unix và C để phát hiện một tín hiệu cụ thể và sau đó, thực hiện một chức năng và sau đó, chấm dứt chương trình bằng "exit (n)" chẳng hạn.

Bạn có thể làm điều đó bằng cách sử dụng signal hoặc sigaction, nhưng vấn đề là bạn chỉ có thể sử dụng phương pháp này cho bất kỳ tín hiệu nào ngoại trừ SIGKILL hoặc SIGSTOP.

0

Không có chức năng nào nắm bắt được tất cả các tình huống và hoạt động trên tất cả các platfrom. Nếu bạn cần một cái gì đó cho Windows, bạn sẽ phải xử lý SEH (xử lý ngoại lệ có cấu trúc). Bạn sẽ phải xác định và thiết lập các trình xử lý cho các kịch bản khác nhau (SEH, C++ Ngoại lệ, SIGABRT, Chấm dứt vv) thực thi mã dọn dẹp thông thường và. Kiểm tra phản ứng của zack ở đây để xử lý tín hiệu SIGABRT.

Đối với SEH, bạn có thể thêm bộ chuyển đổi SE để xử lý các ngoại lệ SE và chuyển đổi chúng thành ngoại lệ C++, xem _set_se_translator để biết thêm thông tin về cách xử lý các ngoại lệ SEH.

Bạn có thể tham khảo this documentation for set_terminate handlerthis is a good reference for set_unexpected.

Bạn sẽ phải viết trình xử lý của riêng bạn sẽ được gọi cho mọi tình huống.

Cuối cùng, tôi sẽ khuyên bạn nên sử dụng một số thư viện hiện có cho mục đích này, tôi thích crashrprt.

+0

Tôi đang làm việc trên Windows .. Mục đích của câu hỏi là một số hoạt động làm sạch tôi muốn đặt theo cách như vậy mà không có vấn đề tại sao và từ nơi thoát chương trình (duyên dáng hoặc tai nạn) Nó nên làm .. – NoName

+0

Kiểm tra phản hồi cập nhật của tôi . – user258808

0

Bạn có quen thuộc với xử lý tín hiệu không? Tôi khuyên bạn nên nghiên cứu điều đó trước và sau đó quay trở lại với các câu hỏi liên quan đến nó.Nó trông giống như một vài người đã ám chỉ đến nó, nhưng đây là một nguồn lực tốt để kiểm tra:

http://www.gnu.org/s/hello/manual/libc/Signal-Handling.html

Viết xử lý tín hiệu riêng của bạn sẽ cho phép bạn để xác định những gì bạn muốn làm gì khi một tín hiệu đặc biệt là bắt. Như đã nói, có một số không thể bị ghi đè và vì lý do chính đáng. Bạn không muốn để ai đó ghi đè kill -9 đơn giản chỉ vì một chương trình không thể giết được có thể được tạo ra. Tuy nhiên, một tín hiệu giết thẳng hoặc một cái gì đó như ctrl-c, ctrl-d, vv, có thể bị bắt và xử lý theo cách bạn chọn.

7

Tùy thuộc vào những gì bạn có nghĩa là bởi "chấm dứt đột ngột" có những lựa chọn khác nhau:

  • hủy toàn cầu sẽ được kêu gọi bình thường chấm dứt (trở về từ main, hoặc gọi đến exit()).
  • atexit() đăng ký một chức năng được gọi là chấm dứt thông thường.
  • std::set_terminate đăng ký một hàm sẽ được gọi khi ngoại lệ được ném nhưng không bị bắt hoặc khi "xử lý ngoại lệ phải bị chấm dứt vì một số lý do khác".
  • sigaction() chức năng đăng ký được gọi khi chương trình của bạn nhận được tín hiệu, nhiều trong số đó thường sẽ đột ngột chấm dứt chương trình của bạn. Trình xử lý tín hiệu có thể được gọi khi chương trình ở trạng thái không nhất quán bên trong và do đó, cực kỳ bị giới hạn ở những gì chúng có thể thực hiện. Ví dụ, họ không thể làm bất cứ điều gì có thể cấp phát bộ nhớ. Ngoài ra, API này không có sẵn trên Windows; có tương đương nhưng tôi không quen thuộc với họ.

Lưu ý rằng tất cả các hệ điều hành sử dụng chung đều cung cấp ít nhất một cách để đột ngột chấm dứt chương trình của bạn mà không thể bị chặn khỏi mã của bạn. Ví dụ, Unix có tín hiệu 9 (SIGKILL) mà bạn không thể đăng ký một trình xử lý. Đây là một tính năng, không phải là lỗi. Bạn, người dùng, cần một cách để làm cho một quá trình biến mất ngay cả khi nó đã làm mọi thứ trong khả năng của mình để làm cho bản thân không thể phá hủy. Hơn nữa, không có mã nào có thể bảo vệ quá trình của bạn khi con thỏ con vật cưng của người dùng gặm nhấm thông qua dây nguồn trên máy tính. Bởi vì điều này, nó có thể là một sử dụng tốt hơn thời gian của bạn để thiết kế chương trình của bạn để phục hồi từ tai nạn sạch, thay vì cố gắng để làm sạch khi một vụ tai nạn xảy ra. Xem bài viết này trên "crash-only design" để biết thêm về điều đó.

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