Python উপপ্রক্রিয়ায় একটি প্রোগ্রাম এর stdout 10% হারানো

আমি একটি প্রোগ্রাম যা Python সঙ্গে একটি সাবপ্রসেস হিসাবে বলা প্রয়োজন। প্রোগ্রামটি জাভাতে লেখা হয়েছে। হ্যাঁ আমি জানি...

যাইহোক, আমি বলেন প্রোগ্রাম থেকে আউটপুট সব ক্যাপচার করতে হবে।

দুর্ভাগ্যবশত, যখন আমি সাবপ্রোকাইস.পপেন ২ বা সাবফ্র্যাক্সেসকে কল করি। [0] সাথে যোগাযোগ করুন, যখন আমি একটি সাবপ্রোসিস ব্যবহার করছি তখন আমি আউটপুট ডাটাটির প্রায় 10% হ্রাস করছি। পিডিপি stdout এ নির্ধারিত এবং যখন আমি একটি ফাইল বর্ণনাকারী ব্যবহার করছি (একটি খোলা থেকে ফিরে) stdout নির্ধারিত।

উপপ্রক্রিয়ায় ডকুমেন্টেশনটি স্পষ্টভাবে স্পষ্ট হয় যে উপপ্রক্রিয়াকে ব্যবহার করা হয়। পিপিই যদি আপনি একটি শিশু প্রক্রিয়া থেকে সব আউটপুট ক্যাপচার করার চেষ্টা করছেন তাহলে অস্থির হয়।

আমি বর্তমানে oumput একটি tmp ফাইল মধ্যে ডাম্প প্রক্সি ব্যবহার করছি কিন্তু যে সুস্পষ্ট কারণ জন্য চিরকালের গ্রহণ করা হচ্ছে।

আমি ডিস্ক লেখাগুলি এড়াতে মেমরিতে সব ডেটা রাখতে চাই।

কোন সুপারিশ স্বাগত! ধন্যবাদ!

import subprocess

cmd = 'java -Xmx2048m -cp "/home/usr/javalibs/class:/home/usr/javalibs/libs/dependency.jar" --data data --input input" 

# doesn't get all the data
#
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]

OR
# doesn't get all the data
#
fd = open("outputfile",'w')
p = subprocess.Popen(cmd, stdout=fd, shell=True)
p.communicate()
fd.close() # tried to use fd.flush() too.

# also tried
# p.wait() instead of p.communicate(), but wait doesn't really wait for the java program to finish running - it doesn't block

OR
# also fails to get all the data
#
import popen2
(rstdout, rstdin) = popen2.popen2(cmd)

প্রত্যাশিত আউটপুট অ্যাসসিআই লাইনের একটি সিরিজ (কয়েক হাজার হাজার)। লাইন সংখ্যা এবং একটি লাইন অক্ষর শেষ থাকে

0\n
1\n
4\n
0\n
...
2
যোগ সম্পাদিত
মতামত: 1
আমরা কিছু পাইথন কোড আছে কি?
যোগ লেখক Bittrance, উৎস
Hey, শুধু stdout (stderr নয়) ক্যাপচার করার চেষ্টা করছে আউটপুট একটি সংখ্যা এবং লাইন অক্ষর শেষ - এটি সমস্ত আসি আউটপুট আশা করা হচ্ছে
যোগ লেখক ct_, উৎস
@ jadkik94 এবং পল তাই বলছি আমি আপনার সময় প্রশংসা করি কিন্তু আপনি সত্যিই সাহায্য না করছি। আমি আগেই বলেছি যে পিপিই (পিআইপিআই) এর উপপ্রক্রিয়াকে কল করার সময় কিছু সমস্যা রয়েছে (আমি কয়েকবার ডকুমেন্টেশনটি পড়েছি) তাই কিভাবে এটি সঠিকভাবে করবেন?
যোগ লেখক ct_, উৎস
@ দ্য পল এটি সব আউটপুট পড়া হয় না। ইনপুটগুলির উপর নির্ভর করে - আমি নতুন লাইন অক্ষর দিয়ে ~ 1300 + সংখ্যক লাইনের আশা করছি। এবং হ্যাঁ অপেক্ষা করুন সত্যিই "অপেক্ষা" না আমার পাইথন স্ক্রিপ্ট অতীত execution চলতে যেখানে আমি উপপ্রক্রিয়ক outk। সঠিকতার জন্য, আমি সমস্যা করছি ব্যাখ্যা করছি।
যোগ লেখক ct_, উৎস
@ পল, আমি একটি প্রতিক্রিয়া হিসাবে খুঁজছি না কি বেশ। যদি এটি অস্থির হয় তবে আমি কিভাবে সঠিকভাবে এটি কিভাবে করতে পারি সে সম্পর্কে আমি পড়তে পারি এবং যখন আমি fd ব্যবহার করি তখনও আমি সমস্ত তথ্য পাচ্ছি না - আমি stdout- এ একটি fd উল্লেখ করার জন্য সন্দেহভাজন হিসাবে subprocess.PIPE assigning হিসাবে একই সমস্যা আছে stdout।
যোগ লেখক ct_, উৎস
আউটপুট শেষ 10%। স্পষ্টতা প্রশ্নটি একটি আপডেট পোস্ট। ধন্যবাদ!
যোগ লেখক ct_, উৎস
যা "10%" আপনি অনুপস্থিত? এটা শুরুতে শেষ হয়? আপনি কি আউটপুট আশা ছিল?
যোগ লেখক Joel Cornett, উৎস
"কিন্তু জাভা প্রোগ্রাম চালানোর শেষের জন্য অপেক্ষা না করেই অপেক্ষা করছে - এটি ব্লক করে না" <- সম্পূর্ণভাবে ভুল। আপনি কি আপনার সাবপ্রসেসটি যেভাবে আশা করেন তার কাজ করছেন তা আপনি কি নিশ্চিত?
যোগ লেখক the paul, উৎস
আপনি কি ত্রুটি পাচ্ছেন?
যোগ লেখক the paul, উৎস
ডান, subprocess.PIPE ব্যবহার করা উচিত যোগাযোগ() </কোড> বা অন্যথায় সাবধানতা সঙ্গে, প্রতিটি অন্যান্য ব্লক থেকে ইনপুট এবং আউটপুট FDA রাখা যে আংশিকভাবে আমি "সঠিকভাবে ব্যবহৃত" দ্বারা বোঝানো কি
যোগ লেখক the paul, উৎস
"উপপ্রক্রিয়ায় ডকুমেন্টেশনটি সাবপ্রক্রাস ব্যবহার করে খুব স্পষ্ট হয়। পিপিই যদি আপনি একটি শিশু প্রক্রিয়া থেকে সব আউটপুট ক্যাপচার করার চেষ্টা করছেন অস্থির হয়।" <- যদি ডকুমেন্টেশন এই বলে, এটি সম্পূর্ণরূপে ভুল। পাইপ পুরোপুরি নিরাপদ এবং সঠিকভাবে ব্যবহৃত হলে সংযুক্ত fd এর সমস্ত আউটপুট পাবেন।
যোগ লেখক the paul, উৎস
আপনি কি নিশ্চিত যে আপনার জাভা সাবপ্রোশন নিজে ফাঁকা নয়? যে আপনার অপেক্ষা করতে() কলটি ব্লক করা হবে না কেন তা ব্যাখ্যা করতে পারে।
যোগ লেখক the paul, উৎস
আমি আপনাকে আশ্বস্ত করি, যদি আপনি যোগাযোগ ব্যবহার করেন এবং আপনার ডেটা মেমরিতে ফিট করে (যদি এটি না হয় তবে আপনি আরও বেশি সুস্পষ্ট ব্যর্থতা দেখতে পান) PIPE এর "সমস্যা" নেই ডক্সের নোটগুলি মানুষকে একটি অনুপযুক্ত উপায়ে এটি ব্যবহার করার চেষ্টা করা থেকে রক্ষা করতে হয়। আমি সাহায্য চাই, কিন্তু মনে হচ্ছে আপনি আসলে সিস্টেমের ভুল অংশকে দোষ দিতে চান।
যোগ লেখক the paul, উৎস
subprocess.PIPE ব্যবহার করে অথবা সাবপ্রসেসের আউটপুটে একটি fd কে নিয়োজিত করা হয় এমন একটি নির্দিষ্ট জিনিসটি মূলত একই জিনিস যা আপনার শেলটি যখন আপনি একটি ফাইল (অপারেটিং সিস্টেমের dup2 ( ) </কোড> সিস্টেম কল)। আপনি নিরাপদে অনুভব করতে পারেন যে অংশ কাজ করছে। আপনি সেখানে আপনার কমান্ডের শেষে "` | tee আউটপুটকপি "যোগ করার চেষ্টা করতে পারেন; তারপর আপনি চেক করতে পারেন যে আউটপুটকপি `আপনার আশা সমস্ত লাইন আছে। যদি না হয়, আপনার জাভা প্রোগ্রামটি বেশ সঠিকভাবে কাজ করছে না।
যোগ লেখক the paul, উৎস
@ jadkik94 যে এখানে একটি সমস্যা হতে খুব অসম্ভাব্য; পাইথন বা জাভা চালাতে সক্ষম কোন ধারণাযোগ্য মেশিনে, "কয়েক হাজার" অক্ষরের প্রতিটি লাইন সহজেই মেমরিতে লাগবে।
যোগ লেখক the paul, উৎস
এটা কি কিছু আউটপুট stderr যাও লেখা হচ্ছে সম্ভব?
যোগ লেখক Jeremiah, উৎস
"উল্লেখ্য এই ফাংশনের সাথে stdout = PIPE বা stderr = PIPE ব্যবহার করবেন না। যেহেতু পাইপগুলি বর্তমান প্রক্রিয়ায় পড়ছে না, তবে এটি একটি পিপের জন্য যথেষ্ট আউটপুট তৈরি করলে ওএস পাইপ বাফারটি পূরণ করতে পারে।" সাবপ্রসেস ডক্স থেকে
যোগ লেখক jadkik94, উৎস
বড় ডেটা সম্পর্কে যোগাযোগ করা এ একটি সতর্কবাণী আছে, কিন্তু এটি এখনও একটি বিকল্প জন্য খুব স্পষ্ট হয় ...
যোগ লেখক jadkik94, উৎস
দেখুন যে এটিও সাহায্য করতে পারে: অন্য একটি প্রশ্ন
যোগ লেখক jadkik94, উৎস

2 উত্তর

এটি আসলে এমন কিছু প্রক্রিয়ার সাথে জড়িত যা আপনি আসলে কল করছেন। আপনি অন্য Python স্ক্রিপ্টের সাথে একটি সাধারণ পরীক্ষা করে এটি যাচাই করতে পারেন যা রেখার কাজ করে:

পারে out.py করুন

import sys

for i in xrange(5000):
    print "%d\n" % i

sys.exit(0)

পারে test.py করুন

import subprocess

cmd = "python out.py"
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]

print output

তাই আপনি যাচাই করতে পারেন যে এটি যে সমস্যাটি না হয় তার আকারের আকার, বরং আপনি যা কল করছেন তার সাথে যোগাযোগ করুন।

আপনার চলমান পিথনের সংস্করণটিও নিশ্চিত করতে হবে, যেমন আমি পপেনের অভ্যন্তরীণ বাফার বিষয়ে অতীতের সমসাময়িক বিষয়ে পড়েছি (কিন্তু আপনি যে আমার জন্য সেটাকে নির্দিষ্ট করেছেন তার একটি পৃথক ফাইল হ্যান্ডেল ব্যবহার করে)।

এটি একটি বাফার সমস্যা হবে যদি উপধারা কল অনিশ্চিতভাবে ঝুলন্ত ছিল। কিন্তু প্রক্রিয়াটি সম্পন্ন হলে কেবল লাইনের অভাব হয়, তাহলে Popen তার কাজ করছে।

2
যোগ
আমি এটি একটি স্পিন একটি বিট দিতে হবে, এবং ফলাফল পোস্ট করা হবে, ধন্যবাদ!
যোগ লেখক ct_, উৎস

আমি subprocess ব্যবহার করে stdout তে অনেক বড় আউটপুট ব্যবহার করেছি কিন্তু এই ধরনের সমস্যা দেখা যায় নি। আপনি কি দেখানো থেকে মূল কারণ কি এটা উপসংহার করা কঠিন। আমি নিম্নলিখিত চেক করবে:

যেহেতু p.wait() আপনার জন্য কাজ করেনি এটি এমন হতে পারে যে আপনি যখন PIPE পড়ছেন তখন আপনার জাভা প্রোগ্রাম শেষ 10% মুদ্রণ করতে ব্যস্ত। সরাসরি p.wait() পান

  • আপনি PIPE পড়ার আগে যথেষ্ট পরিমাণে অপেক্ষা করুন (30 সেকেন্ড বলবেন), আপনার 10% দেখায়?
  • এটা সন্দেহজনক যে p.wait() আপনার জাভা প্রোগ্রামে ব্লক করে না। আপনার জাভা প্রোগ্রামটি অন্য প্রোগ্রামের অধীনস্থ করে?
  • p.wait() এর রিটার্ন মান চেক করুন। আপনার জাভা প্রোগ্রামটি কি সাধারণত বন্ধ ছিল?

যদি সমস্যা আপনার সামঞ্জস্যের মডেল না থাকে, তাহলে চেক করুন যে আপনি আপনার জাভা প্রোগ্রামে সঠিকভাবে মুদ্রণ করছেন কিনা:

  • আপনি কি আপনার জাভা প্রোগ্রামে stdout মুদ্রণ করতে ব্যবহৃত ফাংশনটি ব্যবহার করেছেন? IOException ?
  • এর প্রবণতা বা অগ্রাহ্য করে কি?
  • আপনি কি স্ট্রিমটি সঠিকভাবে ফ্লাশ করেছেন? যখন আপনার জাভা প্রোগ্রাম বন্ধ হয়ে যায়, তখন যথোপযুক্ত ফ্লাশিং ছাড়াই শেষ 10% আপনার বাফার হতে পারে।
2
যোগ
আপনার সাথে ডান ফিরে পাবেন - একটি বিট মধ্যে jdi এর নোট কাজ যাচ্ছে। ধন্যবাদ!
যোগ লেখক ct_, উৎস