पायथन के साथ एक विशाल सीएसवी का प्रसंस्करण जब अचानक बंद हो जाता है, तो 'मारे गए' का क्या मतलब है?


89

मेरे पास एक पायथन स्क्रिप्ट है जो एक बड़ी 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])

और Killedबाद finished countingमें मुद्रित होता है , और पूरा संदेश है:

killed (program exited with code: 137)

6
आपको मिल रहे त्रुटि संदेश का सटीक शब्दांकन पोस्ट करें।
रॉबर्ट हार्वे

2
"मार दिया" आम तौर पर इसका मतलब है कि इस प्रक्रिया को कुछ संकेत मिले जिससे यह बाहर निकल गया। इस मामले में चूंकि यह स्क्रिप्ट के एक ही समय में हो रहा है इसलिए एक अच्छा मौका है कि यह एक टूटी हुई पाइप है, प्रक्रिया एक फ़ाइल हैंडल से पढ़ने या लिखने की कोशिश कर रही है जिसे दूसरे छोर पर बंद कर दिया गया है।
एंड्रयू क्लार्क

3
यह इस बारे में कोई जवाब नहीं है कि killedसंदेश कहाँ से आता है, लेकिन यदि यह किसी प्रकार की सिस्टम मेमोरी सीमा से अधिक होने के कारण है, तो आप अपने अंतिम लूप के counter.iteritems()बजाय इसका उपयोग करके इसे ठीक करने में सक्षम हो सकते हैं counter.items()। पायथन 2 itemsमें, शब्दकोश में कुंजियों और मूल्यों की एक सूची देता है, जिसे बहुत बड़ी होने पर बहुत अधिक मेमोरी की आवश्यकता हो सकती है। इसके विपरीत, iteritemsएक जनरेटर है जिसे केवल किसी भी समय थोड़ी मात्रा में मेमोरी की आवश्यकता होती है।
२०:

जवाबों:


101

बाहर निकलें कोड 137 (128 + 9) इंगित करता है कि आपका कार्यक्रम सिग्नल 9 प्राप्त करने के कारण बाहर निकल गया, जो कि है SIGKILL। यह भी killedसंदेश समझाता है । सवाल यह है कि आपको वह संकेत क्यों मिला?

सबसे संभावित कारण संभवतः यह है कि आपकी प्रक्रिया सिस्टम संसाधनों की मात्रा में कुछ सीमा पार कर गई है जिसे आपको उपयोग करने की अनुमति है। आपके OS और कॉन्फ़िगरेशन के आधार पर, इसका मतलब यह हो सकता है कि आपके पास बहुत अधिक खुली हुई फाइलें थीं, बहुत अधिक फ़ाइल साइट या कुछ और का उपयोग किया गया था। सबसे अधिक संभावना है कि आपका कार्यक्रम बहुत अधिक मेमोरी का उपयोग कर रहा था। मेमोरी एलोकेशन विफल होने पर चीजों को तोड़ने के बजाय, सिस्टम ने प्रक्रिया को एक किल सिग्नल भेजा जो बहुत अधिक मेमोरी का उपयोग कर रहा था।

जैसा कि मैंने पहले टिप्पणी की थी, मुद्रण के बाद एक मेमोरी सीमा पर एक कारण यह हो सकता finished countingहै कि counter.items()आपके अंतिम लूप में आपका कॉल एक सूची आवंटित करता है जिसमें आपके शब्दकोश से सभी कुंजी और मान शामिल हैं। यदि आपके शब्दकोश में बहुत अधिक डेटा है, तो यह एक बहुत बड़ी सूची हो सकती है। एक संभावित समाधान का उपयोग करना होगा counter.iteritems()जो एक जनरेटर है। किसी सूची में सभी वस्तुओं को वापस करने के बजाय, यह आपको कम स्मृति उपयोग के साथ उन पर पुनरावृति करने देता है।

तो, मैं आपको अंतिम लूप के रूप में यह कोशिश करने का सुझाव दूंगा:

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

ध्यान दें कि पायथन 3 में, items"डिक्शनरी व्यू" ऑब्जेक्ट देता है जिसमें पाइथन 2 के संस्करण के समान ओवरहेड नहीं है। यह प्रतिस्थापित करता है iteritems, इसलिए यदि आप बाद में पायथन संस्करणों को अपग्रेड करते हैं, तो आप लूप को वापस उसी तरह से बदल देंगे जैसे वह था।


2
सही है, लेकिन खुद शब्दकोश भी बहुत सारी मेमोरी लेगा। ओपी को एक साथ सभी के बजाय वृद्धिशील रूप से फ़ाइल को पढ़ने और संसाधित करने पर विचार करना चाहिए।
केविन

24

इसमें दो संग्रहण क्षेत्र शामिल हैं: स्टैक और हीप। स्टैक वह जगह है जहां एक विधि कॉल की वर्तमान स्थिति रखी जाती है (यानी स्थानीय चर और संदर्भ), और ढेर वह जगह है जहां ऑब्जेक्ट संग्रहीत होते हैं। पुनरावृत्ति और स्मृति

मुझे लगता है कि हुकुम में बहुत सी चाबियां counterहैं जो ढेर क्षेत्र की बहुत अधिक मेमोरी का उपभोग करेगी, इसलिए पायथन रनटाइम एक आउटऑफमेरी अपवाद को बढ़ाएगा ।

इसे बचाने के लिए, एक विशाल वस्तु न बनाएं, जैसे काउंटर

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

संदर्भ

2

मुझे संदेह है कि कुछ भी प्रक्रिया को सिर्फ इसलिए मार रहा है क्योंकि इसमें लंबा समय लगता है। उदारतापूर्वक मारे गए का अर्थ है कि बाहर से कुछ इस प्रक्रिया को समाप्त कर दिया गया, लेकिन शायद इस मामले में Ctrl-C को मारना नहीं है, क्योंकि यह कीबोर्डइंटरेरिएट अपवाद पर पायथन से बाहर निकलने का कारण होगा। इसके अलावा, पायथन में आपको मेमोरीएयर का अपवाद मिलेगा यदि यह समस्या थी। क्या हो सकता है कि आप पायथन या मानक पुस्तकालय कोड में एक बग मार रहे हैं जो प्रक्रिया के दुर्घटना का कारण बनता है।


दुर्घटनाग्रस्त बग के परिणामस्वरूप सेगफॉल्ट होने की संभावना अधिक होगी SIGKILL, जब तक कि पायथन raise(SIGKILL)किसी कारण से अपने कोड में कहीं न हो।
केविन

1
अजगर में एक बग SIGKILL नहीं भेजेगा।
क्वीन

2

सबसे अधिक संभावना है, आप स्मृति से बाहर भाग गए, इसलिए कर्नेल ने आपकी प्रक्रिया को मार दिया।

क्या आपने OOM किलर के बारे में सुना है ?

यहाँ एक स्क्रिप्ट है जो मैंने CSV फ़ाइलों से डेटा के एक विशाल सेट को संसाधित करने के लिए विकसित की है:

Mar 12 18:20:38 server.com kernel: [63802.396693] Out of memory: Kill process 12216 (python3) score 915 or sacrifice child
Mar 12 18:20:38 server.com kernel: [63802.402542] Killed process 12216 (python3) total-vm:9695784kB, anon-rss:7623168kB, file-rss:4kB, shmem-rss:0kB
Mar 12 18:20:38 server.com kernel: [63803.002121] oom_reaper: reaped process 12216 (python3), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

से लिया गया था /var/log/syslog

मूल रूप से:

पीआईडी ​​12216 को एक पीड़ित (कुल-वीएम के + 9 जीबी के उपयोग के कारण) के रूप में चुना गया था , इसलिए oom_killer ने इसे पुनः प्राप्त किया।

यहाँ OOM व्यवहार के बारे में एक लेख है


1
+1, बस स्पष्ट करने के लिए, यह समझने के लिए कि मेरा प्रोग्राम कितना RAM उपयोग करने का प्रयास कर रहा है, क्या मुझे कुल-vm, anon-rss, फ़ाइल-rss मानों को जोड़ना चाहिए? इसके अलावा और कुल-वीएम देता है कि मेरा प्रोग्राम वास्तविक उपलब्ध मेमोरी का कितना उपयोग कर रहा है, न कि सही? क्षमा करें, सीमित ज्ञान।
मोमो जूल

1
मेरा ज्ञान इस संदर्भ में @momo पर भी सीमित है। मैं आगे की जांच के लिए थोड़ा समय से बाहर हूं, लेकिन मुझे यह पोस्ट मिली जो मदद कर सकती है: stackoverflow.com/questions/18845857/… । जो मैं आपको बता सकता हूं, क्या वह वास्तव में कुल-वीएम है, प्रक्रिया द्वारा उपयोग की जाने वाली स्मृति की मात्रा है।
ivanleoncz

0

जब मैं VirtualBoxनए Ubuntu 20.04 LTS के भीतर एक साझा फ़ोल्डर से एक अजगर स्क्रिप्ट चलाने की कोशिश की, तो मुझ पर बस वही हुआ । Killedअपने निजी पुस्तकालय को लोड करते समय पायथन ने साथ दिया । जब मैंने फ़ोल्डर को स्थानीय निर्देशिका में स्थानांतरित किया, तो समस्या दूर हो गई। ऐसा प्रतीत होता है कि Killedस्टॉप मेरी लाइब्रेरी के शुरुआती आयात के दौरान हुआ था क्योंकि मुझे फ़ोल्डर के ऊपर ले जाने के बाद मुझे लापता लाइब्रेरी के संदेश मिले थे।

मेरे कंप्यूटर को पुनरारंभ करने के बाद समस्या दूर हो गई।

इसलिए, लोग प्रोग्राम को किसी स्थानीय निर्देशिका में ले जाने की कोशिश कर सकते हैं यदि किसी प्रकार का हिस्सा है या यह एक क्षणिक समस्या हो सकती है जिसके लिए केवल ओएस को रिबूट की आवश्यकता होती है।


रुको, आपको अपने मेजबान या वीएम को रिबूट करना पड़ा?
cglacet

हाँ। मेरे मामले में, मैं एक नया वीएम बना रहा था और जब मैंने इस मुद्दे को देखा तो मैंने पायथन को स्थापित किया था। रिबूट करने के बाद, यह चला गया। मैं चीजों को ठीक करने के एक तरीके के रूप में रिबूटिंग से नफरत करता हूं, इसलिए मैंने डिबग करने की कोशिश करने के लिए और खुदाई के एक घंटे के बाद एसओ में यहां शामिल होने का समय बिताया। लेकिन आखिरकार, मैंने हार मान ली और रिबूट और प्रेस्टो किया। मुझे नहीं पता कि यह क्यों काम किया।
टिमोथी सी। क्विन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.