2009-06-04 34 views
11

Sử dụng đa xử lý trên cửa sổ có vẻ như bất kỳ trình xử lý tệp đang mở nào đều được thừa kế bởi các quy trình được sinh ra. Điều này có tác dụng phụ khó chịu của việc khóa chúng.Ngăn chặn tệp xử lý kế thừa trong đa xử lý lib

Tôi quan tâm đến một trong hai:
1) Ngăn cản việc thừa kế
2) Một cách để giải phóng các tập tin từ quá trình sinh ra

Xét đoạn mã sau đó hoạt động tốt trên OSX, nhưng treo trên cửa sổ tại os.rename

from multiprocessing import Process 
import os 

kFileA = "a.txt" 
kFileB = "b.txt" 

def emptyProcess(): 
    while 1: 
     pass 

def main(): 
    # Open a file and write a message 
    testFile = open(kFileA, 'a') 
    testFile.write("Message One\n") 

    # Spawn a process 
    p = Process(target=emptyProcess) 
    p.start() 

    # Close the file 
    testFile.close() 

    # This will crash 
    # WindowsError: [Error 32] The process cannot access the file 
    #    because it is being used by another process 
    os.rename(kFileA, kFileB) 

    testFile = open(kFileA, 'a') 
    testFile.write("Message Two\n") 
    testFile.close() 

    p.terminate() 


if __name__ == "__main__": 
    main() 

Trả lời

0

Sau khi bạn mở một tập tin xử lý, bạn có thể sử dụng SetHandleInformation() để loại bỏ các HANDLE_FLAG_INHERIT cờ.

+0

Làm cách nào để có được xử lý tệp từ nội dung được tạo bằng open(), không phải là os.open()? – 14256424

1

Tôi không biết về mô-đun đa xử, nhưng với các module subprocess bạn có thể hướng dẫn nó để không thừa hưởng bất kỳ file descriptor:

If close_fds is true, all file descriptors except 0, 1 and 2 will be closed before the child process is executed. (Unix only). Or, on Windows, if close_fds is true then no handles will be inherited by the child process. Note that on Windows, you cannot set close_fds to true and also redirect the standard handles by setting stdin, stdout or stderr.

Hoặc bạn có thể đóng tất cả các file descriptor trong quá trình con bạn với os.closerange

Close all file descriptors from fd_low (inclusive) to fd_high (exclusive), ignoring errors. Availability: Unix, Windows.

+2

Tôi biết về cờ xử lý con, nhưng tôi đặc biệt hỏi về mô-đun đa xử lý. Ngoài ra, nếu chúng ta có một đường ống hoặc tập tin khác, chúng ta muốn kế thừa cờ close_fds thì hơi nặng. – 14256424

+0

@vilalian Trong trường hợp bạn muốn giữ lại các bộ mô tả tệp được kế thừa, bạn cần chuyển thông tin này đến tiến trình con để nó biết (các) trình mô tả tệp nào không đóng. Không có cách nào khác. – lothar

4

Phương thức fileno() trả về số tệp được chỉ định bởi thư viện thời gian chạy. Cho số tập tin, sau đó bạn có thể gọi msvcrt.get_osfhandle() để xử lý tập tin Win32. Sử dụng tay cầm này trong cuộc gọi đến SetHandleInformation. Vì vậy, một cái gì đó như sau có thể làm việc:

win32api.SetHandleInformation(
    msvcrt.get_osfhandle(testFile.fileno()), 
    win32api.HANDLE_FLAG_INHERIT, 
    0) 

Tôi không chắc chắn về việc sử dụng chính xác của các mô-đun win32api, nhưng điều này sẽ giúp thu hẹp khoảng cách giữa một đối tượng file Python và một tay cầm Win32.

0

Tôi đã gặp sự cố này khi sử dụng nhật ký xoay và xử lý đa. Khi quá trình cha mẹ cố gắng xoay nhật ký, nó không thành công với một

WindowsError: [Error 32] The process cannot access the file because it is being used by another process

dựa trên một số các câu trả lời khác, sau đây là một giải pháp làm việc trong python 2.7 để ngăn chặn xử lý tập tin đăng nhập từ được thừa hưởng

fd = logging.getLogger().handlers[0].stream.fileno() # The log handler file descriptor 
fh = msvcrt.get_osfhandle(fd) # The actual windows handler 
win32api.SetHandleInformation(fh, win32con.HANDLE_FLAG_INHERIT, 0) # Disable inheritance 

Xin lưu ý vấn đề này phần nào được giải quyết trong trăn 3.4. để biết thêm thông tin, hãy xem https://www.python.org/dev/peps/pep-0446/

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