2012-05-21 53 views
7

Tôi đang tái cấu trúc mã cũ và một trong những điều tôi muốn giải quyết là cách xử lý lỗi. Tôi nhận thức được ngoại lệ và cách họ làm việc, nhưng tôi không hoàn toàn chắc chắn họ là giải pháp tốt nhất cho các tình huống tôi đang cố gắng xử lý.Làm cách nào để kết thúc chương trình C++ sau khi bị lỗi?

Trong mã này, nếu mọi thứ không xác thực, thực sự không có lý do hoặc lợi thế nào để giải phóng chồng. Đã được thực hiện. Không có vấn đề gì trong việc cố gắng cứu con tàu, bởi vì nó là một mã không tương tác chạy song song thông qua Sun Grid Engine. Người dùng không thể can thiệp. Hơn nữa, những thất bại xác nhận này không thực sự đại diện cho hoàn cảnh đặc biệt. Họ dự kiến.

Vậy làm cách nào để giải quyết tốt nhất vấn đề này? Một điều tôi không chắc chắn tôi muốn là một điểm xuất cảnh trong mọi phương pháp lớp có thể thất bại. Điều đó dường như không thể duy trì được. Liệu tôi có sai? Thực tế có chấp nhận được để chỉ gọi exit() hoặc abort() tại điểm không thành công trong các mã như thế này? Hoặc tôi nên ném một ngoại lệ tất cả các cách trở lại một số tuyên bố bắt chung trong chính? Lợi thế là gì?

+0

Có bất kỳ điều gì tốt từ việc khôi phục từ ngoại lệ hoặc bạn chỉ muốn thoát ra bất cứ khi nào có lỗi xảy ra? Không phải là nó quá nhiều khi ứng dụng của bạn bị treo mỗi khi có lỗi xảy ra? – DumbCoder

+0

Tôi đang sử dụng ngoại lệ và các trường hợp tương tự cho các vấn đề không nghiêm trọng. Tôi thực sự đang cố gắng giải quyết tình huống lỗi nghiêm trọng ở đây. – Fadecomic

Trả lời

4

Ném ngoại lệ để bị phát hiện chính và sau đó thoát ra nghĩa là các đối tượng tài nguyên RAII của bạn được dọn sạch. Trên hầu hết các hệ thống, điều này không cần thiết đối với nhiều loại tài nguyên. Hệ điều hành sẽ dọn sạch bộ nhớ, xử lý tệp, v.v.(mặc dù tôi đã sử dụng một hệ thống không giải phóng bộ nhớ có nghĩa là nó vẫn được cấp phát cho đến khi hệ thống khởi động lại, vì vậy bị rò rỉ khi thoát chương trình không phải là một ý tưởng hay.)

Nhưng có các loại tài nguyên khác mà bạn có thể muốn phát hành sạch như mạng hoặc kết nối cơ sở dữ liệu hoặc thiết bị cơ khí bạn đang lái xe và cần phải tắt an toàn. Nếu một ứng dụng sử dụng rất nhiều thứ như vậy thì bạn có thể muốn ném một ngoại lệ để thư giãn ngăn xếp trở lại chính, và sau đó thoát ra.

Vì vậy, phương pháp thoát thích hợp tùy thuộc vào ứng dụng. Nếu một ứng dụng biết nó an toàn thì gọi _Exit(), abort(), exit(), hoặc quickexit() có thể hoàn toàn hợp lý. (Mã thư viện không nên gọi chúng, vì rõ ràng là thư viện không biết liệu nó có an toàn cho mọi ứng dụng sẽ sử dụng thư viện không.) Nếu có một số vấn đề quan trọng cần phải thực hiện trước khi một ứng dụng thoát nhưng bạn biết nó bị giới hạn , sau đó ứng dụng có thể đăng ký làm sạch mã thông qua atexit() hoặc at_quick_exit().

Vì vậy, về cơ bản quyết định những gì bạn cần làm sạch, tài liệu, triển khai và cố gắng đảm bảo rằng nó đã được kiểm tra.

2

tôi muốn đề nghị để gọi chức năng toàn cầu

void stopProgram() { 
    exit(1); 
} 

Sau đó bạn có thể thay đổi đó là hành vi, vì vậy nó là duy trì.

+0

Đó là 'void exit (int status)', không phải 'void exit()'. – Griwes

+0

@Griwes: Cảm ơn bạn, đã cập nhật –

1

Như bạn đã chỉ ra, có một số exit hoặc abort được ném xung quanh mã của bạn không thể duy trì được ... ngoài ra, có thể có cơ chế trong tương lai có thể cho phép bạn khôi phục lỗi hoặc xử lý lỗi một cách duyên dáng hơn là chỉ đơn giản là thoát, và nếu bạn đã mã hóa cứng chức năng này, thì sẽ rất khó hoàn tác.

Ném ngoại lệ bị bắt trong số main() là đặt cược tốt nhất vào thời điểm này cũng sẽ cung cấp cho bạn tính linh hoạt trong tương lai nếu bạn chạy mã trong một trường hợp khác. khác nhau. Ngoài ra, việc ném ngoại lệ có thể giúp bạn quyết định thêm hỗ trợ gỡ lỗi, v.v. vì nó sẽ cung cấp cho bạn các điểm để thực hiện các tính năng ghi nhật ký và ghi lại trạng thái chương trình từ các điểm bị cô lập và duy trì trong phần mềm trước khi bạn quyết định để chương trình thoát.

4

Có thể chấm dứt chương trình nếu chương trình không thể xử lý lỗi một cách duyên dáng. Có một vài điều bạn có thể làm:

  • Gọi abort() nếu bạn cần một bãi chứa lõi.
  • Gọi exit() nếu bạn muốn tạo cơ hội chạy đến những thói quen đã đăng ký với atexit() (có nhiều khả năng nhất là gọi destructors cho đối tượng C++ toàn cầu).
  • Gọi _exit() để chấm dứt quá trình ngay lập tức.

Không có gì sai khi sử dụng các chức năng đó miễn là bạn hiểu những gì bạn đang làm, biết các lựa chọn khác của bạn và chọn đường dẫn đó sẵn sàng. Sau khi tất cả, đó là lý do tại sao những chức năng đó tồn tại. Vì vậy, nếu bạn không nghĩ rằng nó làm cho bất kỳ ý nghĩa để cố gắng xử lý các lỗi hoặc làm bất cứ điều gì khác khi nó xảy ra - đi trước. Những gì tôi có thể làm là cố gắng để đăng nhập một số thông tin thông tin (nói, để syslog), và gọi _exit. Nếu đăng nhập không thành công - hãy gọi abort để nhận được một lõi cùng với việc chấm dứt.

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