تجاوز التخزين المؤقت للناتج فرعي أو جانبي مع popen في C أو بيثون

StackOverflow https://stackoverflow.com/questions/1410849

  •  05-07-2019
  •  | 
  •  

سؤال

ولدي سؤال عام حول popen (وجميع وظائف ذات الصلة)، تنطبق على جميع أنظمة التشغيل، عندما أكتب نصي الثعبان أو بعض التعليمات البرمجية ج وتشغيل قابل للتنفيذ الناتجة من وحدة التحكم (الفوز او لينكس)، أستطيع فورا رؤية الإخراج من العملية. ومع ذلك، إذا قمت بتشغيل نفس تنفيذ كعملية متشعب مع المعياري لها توجيهها إلى الأنابيب، ومخازن الانتاج في مكان ما، وعادة ما يصل إلى 4096 بايت قبل أن تتم كتابة إلى الأنابيب حيث عملية الأصل يمكن قراءتها.

والبرنامج النصي الثعبان التالية سوف تولد الانتاج في قطع من 1024 بايت

import os, sys, time

if __name__ == "__main__":
     dye = '@'*1024
     for i in range (0,8):
        print dye
        time.sleep(1)

والبرنامج النصي الثعبان التالية سيتم تنفيذ البرنامج النصي السابق وقراءة الناتج حالما يتعلق الأمر الأنابيب، البايت التي كتبها بايت

import os, sys, subprocess, time, thread

if __name__ == "__main__":
    execArgs = ["c:\\python25\\python.exe", "C:\\Scripts\\PythonScratch\\byte_stream.py"]

    p = subprocess.Popen(execArgs, bufsize=0, stdout=subprocess.PIPE)
    while p.returncode == None:
        data = p.stdout.read(1)
        sys.stdout.write(data)
        p.poll()

وضبط مسار لنظام التشغيل الخاص بك. عند تشغيل في هذا التكوين، لن يظهر الإخراج في قطع 1024 ولكن قطع من 4096، على الرغم من حجم المخزن المؤقت الأمر popen يتم تعيين إلى 0 (الذي هو الافتراضي على أي حال). يمكن لأحد أن يقول لي كيف لتغيير هذا السلوك ؟، هل هناك أي طريقة يمكنني إجبار نظام التشغيل لعلاج الناتج من عملية متشعب في بنفس الطريقة عندما يتم تشغيله من وحدة التحكم ؟، أي مجرد تغذية البيانات من خلال دون التخزين المؤقت؟

هل كانت مفيدة؟

المحلول

في عام، المكتبة C وقت التشغيل القياسية (وهذا ما يعمل نيابة عن مجرد عن كل برنامج على كل نظام، أكثر أو أقل ؛-) يكشف ما إذا المعياري هو محطة أم لا؛ إذا لم يكن كذلك، فإنه مخازن الانتاج (الذي يمكن أن يكون مكسبا كبيرا الكفاءة، مقارنة مع الناتج غير مصقول).

إذا كنت في السيطرة على البرنامج الذي يفعل الكتابة، يمكنك (كما اقترح إجابة أخرى) المعياري تدفق مستمر، أو (أكثر أناقة إذا كان ذلك ممكنا) في محاولة لإجبار المعياري لتكون غير مصقول، على سبيل المثال عن طريق تشغيل بيثون مع العلم -u سطر الأوامر:

-u     : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)
         see man page for details on internal buffering relating to '-u'

و(ما يضيف الصفحة الرجل هو الذكر من ستدين والقضايا مع الوضع الثنائي [ق]).

إذا كنت لا تستطيع أو لا تريد أن تلمس البرنامج الذي هو الكتابة، -u أو ما شابه ذلك على البرنامج الذي مجرد القراءة من غير المرجح أن تساعد (التخزين المؤقت الذي يهم أكثر هو واحد يحدث على المعياري الكاتب، وليس واحد على ستدين القارئ). والبديل هو لخداع الكاتب إلى الاعتقاد بأن انها الكتابة إلى محطة (حتى وإن كان في الواقع انها الكتابة إلى برنامج آخر!)، عن طريق وحدة pty المكتبة القياسية أو طرف ثالث أعلى مستوى على pexpect وحدة (أو ويندوز، مينائها <لأ href =" http://code.google.com/p/wexpect/ " يختلط = "noreferrer"> wexpect ).

نصائح أخرى

وولهذا صحيح، وينطبق على كل من ويندوز ولينكس (وربما غيرها من الأنظمة)، مع popen() وfopen(). إذا كنت تريد المخزن المؤقت للإخراج لترسل قبل 4096 بايت، واستخدام fflush() (على C) أو sys.stdout.flush() (بايثون).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top