Tôi có một chương trình chạy dài có thể có 4 quy trình, nhưng có thể được cấu hình để có nhiều hơn. Tôi đã nghiên cứu logging from multiple processes bằng cách sử dụng số logging
của python và đang sử dụng phương pháp SocketHandler được thảo luận here. Tôi không bao giờ có bất kỳ vấn đề có một logger duy nhất (không có ổ cắm), nhưng từ những gì tôi đọc tôi đã nói với nó sẽ thất bại cuối cùng và bất ngờ. Theo như tôi hiểu nó không biết điều gì sẽ xảy ra khi bạn cố gắng viết vào cùng một tập tin cùng một lúc. Mã của tôi về cơ bản nào sau đây:Ghi nhật ký bằng Python từ nhiều quá trình
import logging
log = logging.getLogger(__name__)
def monitor(...):
# Spawn child processes with os.fork()
# os.wait() and act accordingly
def main():
log_server_pid = os.fork()
if log_server_pid == 0:
# Create a LogRecordSocketServer (daemon)
...
sys.exit(0)
# Add SocketHandler to root logger
...
monitor(<configuration stuff>)
if __name__ == "__main__":
main()
Vì vậy, câu hỏi của tôi là: Tôi có cần phải tạo ra một đối tượng log
mới sau mỗi os.fork()
? Điều gì sẽ xảy ra với đối tượng toàn cầu hiện tại log
?
Khi thực hiện công việc theo cách của tôi, tôi có gặp phải vấn đề mà tôi đang cố tránh (nhiều tệp/ổ cắm mở) không? Điều này sẽ thất bại và tại sao nó sẽ thất bại (Tôi muốn có thể biết được các triển khai tương tự trong tương lai sẽ thất bại)?
Ngoài ra, phương pháp ghi "bình thường" (một log=
) biểu thức ghi vào một tệp từ nhiều quy trình không thành công? Nó có làm tăng IOError/OSError không? Hay nó không hoàn toàn ghi dữ liệu vào tập tin?
Nếu ai đó có thể cung cấp câu trả lời hoặc liên kết để giúp tôi, điều đó thật tuyệt. Cảm ơn.
FYI: Tôi đang thử nghiệm trên Mac OS X Lion và mã có thể sẽ chạy trên CentOS 6 VM trên máy Windows (nếu vấn đề đó). Bất kỳ giải pháp nào tôi sử dụng không cần phải làm việc trên Windows, nhưng nên làm việc trên một hệ thống dựa trên Unix.
CẬP NHẬT: Câu hỏi này đã bắt đầu di chuyển khỏi việc ghi nhật ký hành vi cụ thể và nhiều hơn trong lĩnh vực Linux làm gì với bộ mô tả tệp trong nhánh. Tôi rút ra một cuốn sách giáo khoa đại học và có vẻ như nếu bạn mở một tệp ở chế độ chắp thêm từ hai quy trình (không phải trước một ngã ba) thì cả hai đều có thể ghi vào tệp đúng với điều kiện ghi của bạn không vượt quá bộ đệm hạt nhân thực tế (mặc dù dòng đệm có thể cần phải được sử dụng, vẫn không chắc chắn trên đó). Điều này tạo ra 2 mục bảng tập tin và một mục nhập bảng v-nút. Mở một tập tin sau đó forking không phải là nghĩa vụ phải làm việc, nhưng nó có vẻ miễn là bạn không vượt quá bộ đệm hạt nhân như trước (tôi đã thực hiện nó trong một chương trình trước đó). Vì vậy, tôi đoán, nếu bạn muốn nền tảng độc lập đa xử lý đăng nhập bạn sử dụng ổ cắm và tạo ra một SocketHandler mới sau mỗi ngã ba để được an toàn như Vinay đề nghị dưới đây (mà nên làm việc ở khắp mọi nơi). Đối với tôi, vì tôi có quyền kiểm soát mạnh mẽ những gì hệ điều hành phần mềm của tôi đang được chạy, tôi nghĩ rằng tôi sẽ đi với một đối tượng toàn cầu log
với một FileHandler (mở trong chế độ phụ thêm theo mặc định và dòng đệm trên hầu hết các hệ điều hành). Tài liệu cho open
cho biết "Đệm âm có nghĩa là sử dụng mặc định hệ thống, thường là dòng đệm cho các thiết bị tty và được đệm hoàn toàn cho các tệp khác. Nếu bỏ qua, mặc định hệ thống được sử dụng". hoặc tôi chỉ có thể tạo luồng ghi nhật ký của riêng mình để đảm bảo lưu vào bộ đệm dòng. Và chỉ để được rõ ràng, tôi ok với:
# Process A
a_file.write("A\n")
a_file.write("A\n")
# Process B
a_file.write("B\n")
sản xuất ...
A\n
B\n
A\n
miễn là nó không sản xuất ...
AB\n
\n
A\n
Vinay (hoặc bất cứ ai khác), làm thế nào sai tôi là ai? Cho tôi biết. Cảm ơn bạn cho bất kỳ rõ ràng hơn/độ nhạy bạn có thể cung cấp.
Chủ đề và ổ khóa hữu ích cho những việc như thế này ... –
Tôi cần các quy trình riêng biệt vì trẻ em giao tiếp với các thiết bị bên ngoài nên càng nhanh càng tốt. – daveydave400
Tôi đã cập nhật câu trả lời của mình. –