2013-07-19 18 views
1

我嘗試使用python來處理文本替換問題。有一個Little-endian UTF-16格式的文件,我想替換這個文件中的ip地址。首先,我按行讀取該文件,然後替換目標字符串,最後,我將新字符串寫入文件。但使用多線程操作此文件時,該文件將會出現亂碼。這是我的代碼。python多線程處理文件與fcntl flcok

import re 
import codecs 
import time 
import thread 
import fcntl 

ip = "10.200.0.1" 
searchText = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" 

def replaceFileText(fileName,searchText,replaceText,encoding): 
    lines = [] 
    with codecs.open(fileName,"r",encoding) as file: 
     fcntl.flock(file,fcntl.LOCK_EX) 
     for line in file: 
      lines.append(re.sub(searchText,replaceText,line)) 
     fcntl.flock(file,fcntl.LOCK_UN) 

    with codecs.open(fileName,"w",encoding) as file: 
     fcntl.flock(file,fcntl.LOCK_EX) 
     for line in lines: 
      file.write(line) 
     fcntl.flock(file,fcntl.LOCK_UN) 

def start(): 
    replaceFileText("rdpzhitong.rdp",searchText,ip,"utf-16-le")                 
    thread.exit_thread() 

def test(number): 
    for n in range(number): 
     thread.start_new_thread(start,()) 
     time.sleep(1) 

test(20) 

我不明白爲什麼該文件是亂碼,我使用的fcntl羊羣保持讀/寫序,問題出在哪裏?

回答

4

它是亂碼,因爲鎖的fcntl通過過程擁有,而不是由線程,這樣一個過程不能使用的fcntl連載自己的訪問。例如,請參閱this answer

您需要使用線程構造,如Lock

+1

+1也就是說,fcntl處於進程級別,由進程中的所有線程共享,並且鎖定位於線程級別,與其他線程無關。這些鎖是否獨立於OS實現了python?也就是說,它們在任何操作系統(Windows,類Unix等)中的行爲是否相同? – lulyon

+0

@lulyon,是的,或多或少。 'Lock'是一個python線程結構,可以在任何支持python的平臺上工作。 'fcntl'是一個UNIX-ism,[在Windows上的py上不可用](http://stackoverflow.com/q/1422368/132382)。 – pilcrow

+0

謝謝,這是非常有幫助的。 – lulyon

0

我想它是亂碼,因爲你打開它後會鎖定它。在這種情況下,尋找位置可能是錯誤的。

順便說一句,Python中的線程在這種情況下並不是那麼有用(查看python GIL問題)。爲了最大限度地提高性能,我建議你使用multiprocessing模塊,並使用隊列/管道更改邏輯,使得分析數據的工作進程和從輸入和輸出文件中對I/O負責的主進程。