2013-10-04 90 views
42

我有一個Python腳本,導入一個大的CSV文件,然後統計文件中每個單詞的出現次數,然後將計數導出到另一個CSV文件。'殺死'是什麼意思?

但是,發生的事情是,一旦計數部分完成並且輸出開始,它就在終端中說Killed

我不認爲這是一個內存問題(如果它是我假設我會得到一個內存錯誤,而不是Killed)。

難道這個過程花費的時間太長了嗎?如果是這樣,是否有辦法延長超時期限,以便我可以避免這種情況?

下面是代碼:

csv.field_size_limit(sys.maxsize) 
    counter={} 
    with open("/home/alex/Documents/version2/cooccur_list.csv",'rb') as file_name: 
     reader=csv.reader(file_name) 
     for row in reader: 
      if len(row)>1: 
       pair=row[0]+' '+row[1] 
       if pair in counter: 
        counter[pair]+=1 
       else: 
        counter[pair]=1 
    print 'finished counting' 
    writer = csv.writer(open('/home/alex/Documents/version2/dict.csv', 'wb')) 
    for key, value in counter.items(): 
     writer.writerow([key, value]) 

而且Killedfinished counting打印完之後,情況發生,並且完整的消息是:

killed (program exited with code: 137) 
+6

後你所得到的錯誤消息的確切措辭。 –

+2

「遇難」通常意味着進程收到一些信號導致它退出。在這種情況下,由於它在腳本的同一時間發生,很可能它是一個破損的管道,該進程正在嘗試讀取或寫入已在另一端關閉的文件句柄。 –

+1

這不是一個關於「殺死」消息來自哪裏的答案,但是如果它是由於某種系統內存限制導致的,你可以通過使用'counter.iteritems()'而不是'counter .items()'在你的最後一個循環中。在Python 2中,'items'返回字典中鍵和值的列表,如果它非常大,則可能需要大量內存。相反,'iteritems'是一個發生器,在任何時候只需要少量的內存。 – Blckknght

回答

55

退出代碼137(128 + 9)表示由於接收到信號9(即SIGKILL)而退出程序。這也解釋了killed消息。問題是,你爲什麼收到這個信號?

最可能的原因可能是您的進程超出了允許使用的系統資源的數量限制。根據您的操作系統和配置,這可能意味着您有太多打開的文件,使用了太多的文件空間或其他東西。最有可能的是你的程序使用了太多的內存。當內存分配開始失敗時,系統不會冒險破壞系統,而是向使用太多內存的進程發送kill信號。

正如我前面所述,打印finished counting後可能遇到內存限制的一個原因是您在最後一次循環中調用counter.items()會分配一個列表,其中包含字典中的所有鍵和值。如果你的字典有很多數據,這可能是一個非常大的列表。可能的解決方案是使用counter.iteritems()這是一個發生器。它不會返回列表中的所有項目,而是可以使用更少的內存使用量對它們進行迭代。

所以,我建議想這一點,因爲你最後循環:

for key, value in counter.iteritems(): 
    writer.writerow([key, value]) 

注意的是Python 3,items返回「字典視圖」對象不具有相同的開銷,因爲Python 2裏的版本。它取代了iteritems,所以如果你稍後升級Python版本,你最終會將環路改回原來的樣子。

+1

正確,但字典本身也會佔用很多內存。 OP應該考慮逐步讀取和處理文件,而不是一次全部處理文件。 – Kevin

2

我懷疑什麼是殺害的過程,只是因爲它需要一個長時間。一般來說,殺死意味着外部的東西終止了該進程,但可能不會在這種情況下擊中Ctrl-C,因爲這會導致Python退出KeyboardInterrupt異常。另外,在Python中,如果出現問題,您將得到MemoryError異常。可能發生的是你正在碰到Python或標準庫代碼中的一個錯誤,導致進程崩潰。

+0

一個崩潰的bug比獲得'SIGKILL'更可能導致段錯誤,除非Python由於某種原因在其代碼的某處出現'raise(SIGKILL)'。 – Kevin

14

存在兩個存儲區域:堆棧和堆棧。堆棧是保存方法調用當前狀態的地方(即局部變量和引用),堆是存儲對象的地方。recursion and memory

客串我中有counter字典,這將消耗堆區的內存太多太多的按鍵,讓Python運行時將拋出一個內存溢出例外。

要保存它,請不要創建巨大的對象,例如計數器

1.StackOverflow

,創造了太多的局部變量的程序。

Python 2.7.9 (default, Mar 1 2015, 12:57:24) 
[GCC 4.9.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> f = open('stack_overflow.py','w') 
>>> f.write('def foo():\n') 
>>> for x in xrange(10000000): 
... f.write('\tx%d = %d\n' % (x, x)) 
... 
>>> f.write('foo()') 
>>> f.close() 
>>> execfile('stack_overflow.py') 
Killed 

2.OutOfMemory

是外幣巨人dict包含太多按鍵的程序。

>>> f = open('out_of_memory.py','w') 
>>> f.write('def foo():\n') 
>>> f.write('\tcounter = {}\n') 
>>> for x in xrange(10000000): 
... f.write('counter[%d] = %d\n' % (x, x)) 
... 
>>> f.write('foo()\n') 
>>> f.close() 
>>> execfile('out_of_memory.py') 
Killed 

參考