2016-09-23 22 views
6

Khi chương trình UNIX/C của chúng tôi cần thoát khẩn cấp, chúng tôi sử dụng chức năng thoát (3) và cài đặt bộ xử lý ngoại tuyến (3) để làm sạch khẩn cấp. Cách tiếp cận này làm việc tốt cho đến khi ứng dụng của chúng ta nhận được luồng, tại điểm xử lý atexit() dừng lại để làm việc có thể dự đoán được.Tiêu chuẩn POSIX nói gì về ngăn xếp luồng trong bộ xử lý atexit()? Thực hành hệ điều hành là gì?

Chúng tôi đã học bằng cách dùng thử một lỗi rằng các chuỗi có thể đã chết trong trình xử lý atexit() và ngăn xếp của chúng được phân bổ lại.

Tôi không tìm thấy báo giá trong chuỗi biến mất liên kết tiêu chuẩn với atexit(): chủ đề không còn tồn tại sau khi trả về từ main(), nhưng trước khi gọi atexit() hoặc sau? Thực hành thực tế trên Linux, FreeBSD và Mac là gì?

Có mô hình tốt để dọn dẹp khẩn cấp trong chương trình đa luồng không?

Trả lời

3

Posix Chuẩn

Nó dường như không được xác định bởi Posix liệu atexit xử lý được gọi là trước hoặc sau khi bài được chấm dứt bởi exit.

Có hai (hoặc ba) cách để quá trình chấm dứt "thông thường".

  • Tất cả các chủ đề chấm dứt. Khi thoát khỏi chuỗi cuối cùng, bằng cách quay lại hoặc gọi các trình xử lý pthread_exit, atexit sẽ chạy. Trong trường hợp này không có chủ đề nào khác. (Đây là nền tảng phụ thuộc. Một số nền tảng có thể chấm dứt chủ đề khác nếu chủ đề chính chấm dứt khác hơn là exit, những người khác thì không).

  • Một chuỗi gọi exit. Trong trường hợp này, các trình xử lý atexit sẽ được chạy và tất cả các chuỗi được kết thúc. Posix không xác định thứ tự nào.

  • main trả về. Điều này tương đương với việc gọi số exit() là dòng cuối cùng của main, vì vậy có thể được coi như trên.

OS Practice

Trong Linux, tài liệu https://linux.die.net/man/2/exit nói chủ đề được chấm dứt bởi _exit gọi exit_group, và rằng _exit được gọi sau khi atexit xử lý. Do đó trong Linux khi gọi exit mọi trình xử lý atexit đều chạy trước khi chuỗi được kết thúc. Lưu ý rằng chúng chạy trên thread gọi exit, không phải là chuỗi được gọi là atexit.

Trên Windows, hành vi là như nhau, nếu bạn quan tâm.

Mẫu để dọn dẹp khẩn cấp.

Mẫu tốt nhất là: Không bao giờ ở trạng thái yêu cầu dọn dẹp khẩn cấp.

  • Không có gì bảo đảm rằng dọn dẹp của bạn sẽ chạy vì bạn có thể có một hoặc kill -9 bị cúp điện.
  • Vì vậy, bạn cần có khả năng khôi phục trong trường hợp đó.
  • Nếu bạn có thể khôi phục từ đó, bạn cũng có thể khôi phục từ abort, vì vậy bạn có thể sử dụng abort để thoát khẩn cấp.

Nếu bạn không thể làm điều đó, hoặc nếu bạn có "nice-to-có" dọn dẹp bạn muốn làm, atexit xử lý nên được tốt cung cấp bạn lần đầu tiên một cách duyên dáng dừng tất cả các chủ đề trong quá trình để ngăn chặn bước vào trạng thái không nhất quán trong khi dọn dẹp.

+0

Tôi nghĩ trường hợp sử dụng này nên được ghi chú trong ủy ban POSIX/ISO để thảo luận. Điều đó nói rằng, tôi đồng ý rằng bạn không bao giờ * muốn * ở một nơi mà bạn đang ở trong một tiểu bang nơi bạn cần dọn dẹp, nhưng tôi đã thấy mình ở một nơi như vậy một hoặc hai lần - gần đây nhất nếu tôi tuân thủ TAP mã kiểm tra đơn vị/hồi quy tăng một ngoại lệ, sau đó tôi hoặc không nhận được thông báo đầu ra, hoặc tôi phải xử lý atexit. Không có một định nghĩa nghiêm ngặt về ngoại lệ trong trường hợp đa luồng có thể có vấn đề. – EBo

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