2016-10-11 24 views
5

Tôi đang làm việc với nhiều quy trình và tín hiệu và tôi vừa phát hiện ra rằng printf không phải là chức năng lại, do đó có rủi ro khi sử dụng nó với bộ xử lý tín hiệu. Tôi có thể làm được gì không? Có bất kỳ biến thể tham gia lại của printf hoặc bất kỳ syscall lại entrant có thể thay thế printf?Sử dụng printf làm chức năng tham gia lại C

Cảm ơn!

+1

kiểm tra câu trả lời này để có giải thích chi tiết đáng kinh ngạc: http://stackoverflow.com/questions/3941271/why-are-malloc-and-printf-said-as-non-reentrant – bruceg

+1

Chỉ cần tự hỏi tại sao bạn muốn bật có hai hoặc nhiều quá trình ghi vào một cái gì đó cùng một lúc. WaHrAeT yAoRuE cYoOmUpTlHeItNeKlIyN Gm? Ad? – Tibrogargan

+0

'write' an toàn, vì vậy có thể được sử dụng từ bộ xử lý tín hiệu ... –

Trả lời

4

Trình xử lý tín hiệu rất khó khăn nói chung. Rất phức tạp, thường là thao tác an toàn duy nhất để thực hiện bên trong chúng là đặt cờ "tín hiệu đã nhận" và sau đó để vòng lặp chính (hoặc trong một ứng dụng đa luồng, một chuỗi xử lý tín hiệu đặc biệt) của chương trình thực hiện tín hiệu thực xử lý.

+0

Nếu tôi chỉ đặt cờ (như biến tĩnh) trên trình xử lý tín hiệu thì khi mã của tôi quay lại printf, nó sẽ in phần còn lại của tin nhắn? Nếu có thì tại sao nó lại xảy ra? –

+1

Bộ xử lý tín hiệu ngắt mọi thứ đang diễn ra. Nếu printf bị gián đoạn hiện đang ở trong một syscall, kernel thường hủy bỏ hoạt động (nghĩa là reset mọi thứ trở lại trạng thái trước khi yêu cầu syscall) và trở về với errno được đặt thành ERESTART (nên khởi động lại hệ thống bị gián đoạn). Các chức năng thư viện như printf sẽ chỉ trả lại lỗi đó (tức là trả về -1 và để lại errno vì nó). Nếu hàm không nằm trong syscall, nó sẽ chỉ tiếp tục khi bộ xử lý tín hiệu trả về và cách duy nhất để phát hiện sự xuất hiện của tín hiệu là kiểm tra cờ của bạn. –

+0

Tôi hiểu. Vì vậy, làm thế nào tôi có thể sử dụng lá cờ của tôi để khởi động lại printf nếu nó bị gián đoạn bởi một tín hiệu từ hạt nhân? –

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