2009-06-04 7 views
11

विंडोज़ पर मल्टीप्रोसेसिंग का उपयोग करके ऐसा लगता है कि किसी भी खुले फ़ाइल हैंडल स्पॉन्डेड प्रक्रियाओं द्वारा विरासत में प्राप्त होते हैं। यह उन्हें लॉक करने का अप्रिय दुष्प्रभाव है।मल्टीप्रोसेसिंग lib में फ़ाइल हैंडल विरासत को रोकना

मैं में दिलचस्पी रखता हूँ या तो:
1) विरासत
2) पैदा की प्रक्रिया

निम्नलिखित कोड है जिस पर OSX ठीक काम करता है पर विचार करें से फ़ाइल को रिहा करने का एक तरीका है, लेकिन दुर्घटनाओं खिड़कियों पर रोकथाम 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() 

उत्तर

0

आप एक फ़ाइल हैंडल को खोलने के बाद, आप HANDLE_FLAG_INHERIT फ्लैग को निकालना SetHandleInformation() फ़ंक्शन का उपयोग कर सकते हैं।

+0

ओपन(), ओएसओपेन() के साथ बनाए गए किसी चीज़ से फ़ाइल संभाल कैसे प्राप्त करता है? – 14256424

1

मैं बहु मॉड्यूल के बारे में पता नहीं है, लेकिन subprocess मॉड्यूल के साथ आप इसे हिदायत किसी भी फाइल वर्णनकर्ता वारिस नहीं करने के लिए कर सकते हैं:

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.

वैकल्पिक रूप से आप अपने बच्चे को इस प्रक्रिया में सभी फाइल वर्णनकर्ता बंद कर सकता है os.closerange

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

+2

मुझे उपप्रवाह ध्वज के बारे में पता है, लेकिन मैं विशेष रूप से मल्टीप्रोसेसिंग मॉड्यूल के बारे में पूछ रहा हूं। इसके अतिरिक्त, अगर हमारे पास एक और पाइप या फ़ाइल है, तो हम close_fds ध्वज का उत्तराधिकारी होना चाहते हैं, यह थोड़ा भारी हाथ है। – 14256424

+0

@vilalian इस मामले में जहां आप विरासत फ़ाइल डिस्क्रिप्टर रखना चाहते हैं, आपको इस जानकारी को उपप्रोसेसर में पास करने की आवश्यकता होगी ताकि यह जान सके कि कौन सी फाइल डिस्क्रिप्टर बंद नहीं है। कोई अन्य रास्ता नहीं है। – lothar

4

साथ fileno() पद्धति के रूप में क्रम पुस्तकालय द्वारा आवंटित फ़ाइल संख्या दिखाता है। फ़ाइल नंबर को देखते हुए, आप Win32 फ़ाइल हैंडल प्राप्त करने के लिए msvcrt.get_osfhandle() पर कॉल कर सकते हैं। SetHandleInformation पर कॉल में इस हैंडल का उपयोग करें। तो निम्नलिखित की तरह कुछ काम कर सकते हैं:

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

मैं win32api मॉड्यूल का सटीक उपयोग के कुछ नहीं कर रहा हूँ, लेकिन यह एक अजगर फ़ाइल वस्तु और एक Win32 संभाल के बीच की खाई को पाटने में मदद मिलेगी।

0

घुमावदार लॉग और मल्टीप्रोसेसिंग का उपयोग करते समय मुझे इस समस्या का सामना करना पड़ा है। माता-पिता की प्रक्रिया लॉग बारी बारी से करने का प्रयास करता है, यह एक

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

अन्य उत्तर में से कुछ के आधार पर के साथ विफल रहता है, निम्नलिखित अजगर 2.7 में एक काम कर समाधान से विरासत में मिला दिया लॉग फ़ाइल संचालकों को रोकने के लिए है

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 

कृपया ध्यान दें कि यह समस्या पायथन 3.4 में कुछ हद तक पता थी। अधिक जानकारी के लिए https://www.python.org/dev/peps/pep-0446/

संबंधित मुद्दे