[英]Python multithreading issue
碼:
#!/usr/bin/env python
import os
import sys
import threading
class fifo_buffer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.dict_buffer = {}
def run(self):
path = "/media/ramdisk/sample.fifo"
fifo = open(path, "r")
count = 0
for line in fifo:
count = count + 1
self.dict_buffer[count] = line
#print str(count) + " -> " + self.dict_buffer[count]
fifo.close()
def get_packet(self, index):
return self.dict_buffer[index]
def len_dict(self):
print "Length dict: " + str(len(self.dict_buffer))
def main():
fb = fifo_buffer()
fb.start()
print "get_packet(2): " + fb.get_packet(2) # Input Error
fb.len_dict() # Length showing zero
if __name__ == "__main__":
main()
運行功能:
我正在嘗試從fifo文件讀取並將數據存儲到字典中。 此運行功能幾乎無限執行。
get_packet或len_dict函數:
我正在嘗試獲取字典的詳細信息,但無法獲取。
我的疑問是運行功能何時將數據從fifo文件存儲到字典中,而假定使用get_packet或len_dict無限進行,我想訪問此字典數據結構,但無法訪問它
我是線程技術的新手,因此也歡迎使用任何其他方法。
我認為問題可能是您沒有弄清楚多個線程是如何工作的。 調用fb.start()
,兩個線程(從fifo文件讀取並將數據存儲到字典中的主線程和run()
線程)同時工作。
您在調用print "get_packet(2): " + fb.get_packet(2)
時遇到的get_packet(2)
是因為當主線程調用get_packet(2)
, run()
線程尚未將數據追加到字典中。
因此,只有在調用join()之后,才能訪問字典數據?
不完全是。 請繼續閱讀。
在run()線程無限執行時,它們有什么方法可以訪問字典?
你可以處理/訪問字典中run() thread
同時run() thread
正在執行,但很明顯,隨着時間的推移這本詞典的變化,你只能訪問行run() thread
已經處理。 您還可以在run() thread
線程時在主線程中處理/訪問字典,但是正如我之前所說, run() thread
可能沒有將數據追加到字典中(您只能訪問run() thread
也已經處理過)。
我已經測試了代碼,添加了新方法並進行了一些修改。 運行良好。 修改后的代碼如下。
#!/usr/bin/env python
import os
import sys
import threading
class fifo_buffer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.dict_buffer = {}
def run(self):
print("run() starts.")
path = "./sample.fifo"
fifo = open(path, "r")
count = 0
for line in fifo:
count = count + 1
self.dict_buffer[count] = line
print("in for expression: before show_dict()")
self.show_dict() # you could process dict_buffer here, but obviously this dict changes over time, and you could only access the lines that run() thread has already processed.
#print str(count) + " -> " + self.dict_buffer[count]
fifo.close()
print("run() completes.")
def get_packet(self, index):
return self.dict_buffer[index]
def len_dict(self):
print("Length dict: " + str(len(self.dict_buffer)))
def show_dict(self):
print(self.dict_buffer)
def main():
fb = fifo_buffer()
fb.start()
# fb.join()
# print("get_packet(2): " + fb.get_packet(2))
# you could process dict_buffer here, but you could only process/access the lines which run() thread has already processed.
fb.len_dict()
fb.show_dict()
if __name__ == "__main__":
main()
正如我在我的評論說一個,這個例子中(尤其是main
功能) 並不能使從多線程的POV多大意義。 這是對代碼“ 稍微 ”修改的:
#!/usr/bin/env python
import os
import sys
import threading
class FifoBufferThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.dict_buffer = {}
def run(self):
print("Begin inner thread run...")
path = "/media/ramdisk/sample.fifo"
count = 0
with open(path, "r") as fifo:
for line in fifo:
count += 1
self.dict_buffer[count] = line
#print str(count) + " -> " + self.dict_buffer[count]
print("End inner thread run")
def get_packet(self, index):
return self.dict_buffer.get(index, None)
def get_dict_len(self):
return len(self.dict_buffer)
def len_dict(self):
print "Length dict: " + str(self.get_dict_len())
def main():
print("Main thread starting...")
fbt = FifoBufferThread()
fbt.daemon = True
fbt.start()
user_selection = None
while True:
user_selection = raw_input("Press any key to continue, 'x' (lowercase) to exit: ")
if user_selection == "x":
print("Exiting at user's choice.")
break
print(fbt.len_dict())
# Do whatever else you might think is necessary with the dict
print("Exiting")
if __name__ == "__main__":
main()
現在,可以看到主線程與inner( FifoBufferThread
)線程進行交互。
變化 :
main
函數現在是一個循環( 在啟動fbt
線程之后),以更好地說明該線程在后台執行的操作(以及fbt
如何影響主線程)。 它涉及用戶交互(需要按下一個鍵),如果該鍵是小寫的x ,則程序將退出。 fbt.daemon = True
:該線程被標記為守護程序 。 如[Python]:線程對象指出:
線程可以標記為“守護程序線程”。 該標志的重要性在於,僅保留守護程序線程時,整個Python程序都會退出。
get_packet
:我將其修改為使用[Python]:dict.get (並返回None
而不是引發異常並終止程序) get_dict_len
函數(現在由len_dict
)。 最好先獲取數據,然后再格式化以用於打印 我不確定文件的讀取速率,還是其他程序寫入文件的速率,也不確定其初始內容,但是會發生以下情況之一( 假設一旦打開文件即可讀取文件,將在其他進程寫入內容時“更新”其內容):
從TCP讀取的另一個應用程序將寫得足夠快(不太可能),因此讀取文件內容(並將其存儲在dict: IN MEMORY中 )的應用程序最終將耗盡內存
2.1。 一種味道: RAM不會用完,但是磁盤( / media )會用完
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.