سؤال

ولدي مشروع التي اعتقدت كان على وشك أن يكون من السهل نسبيا، ولكن تتحول إلى أن تكون أكثر من الألم الذي كان يأمل. أولا، معظم رمز انا التفاعل مع هو رمز القديمة التي لا أملك السيطرة على، لذلك لا أستطيع أن أفعل التغييرات نموذج كبيرة.

وهنا شرح مبسط للما عليك القيام به: قل لدي عدد كبير من البرامج البسيطة التي يقرأ من ستدين والكتابة إلى المعياري. (وهذه لا أستطيع لمس). في الأساس، ومدخلات لستدين هو أمر مثل "درجة الحرارة تعيين 100" أو شيء من هذا القبيل. والإخراج "تم تعيين درجة الحرارة إلى 100" حدثا أو "وتراجع درجة الحرارة دون المضبوطة مسبقا".

ما أود القيام به هو كتابة تطبيق التي يمكن أن تبدأ مجموعة من هذه البرامج بسيطة، لمشاهدة الأحداث ومن ثم إرسال الأوامر لهم عند الضرورة. كانت خطتي الأولية إلى شيء من هذا القبيل popen، ولكن أحتاج إلى popen ثنائي الاتجاه للحصول على قراءة وكتابة الأنابيب. I اخترق شيء معا أن أدعو popen2 حيث أمرر عليه الأمر لتشغيل واثنين من FILE * أن نمتلئ القراءة والكتابة تيار. ثم كل ما عليك القيام به هو كتابة حلقة البسيطة التي يقرأ من كل من stdouts من كل من هذه العمليات، هل المنطق الذي يحتاج إليه ثم يكتب الأوامر إلى عملية المناسبة.

وإليك بعض شبة الكود

FILE *p1read, *p1write;
FILE *p2read, *p2write;
FILE *p3read, *p3write;

//start each command, attach to stdin and stdout
popen2("process1",&p1read,&p1write);
popen2("process2",&p2read,&p2write);
popen2("process3",&p3read,&p3write);

while (1)
{
   //read status from each process
   char status1[1024];
   char status2[1024];
   char status3[1024];
   fread(status1,1024,p1read);
   fread(status2,1024,p2read);
   fread(status3,1024,p3read);

   char command1[1024];
   char command2[1024];
   char command3[1024];
   //do some logic here

   //write command back to each process
   fwrite(command1,p1write);
   fwrite(command2,p2write);
   fwrite(command3,p3write);
}

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

والآن هذا يعمل كبير على بلدي مربع UNIX وحتى جيدة على مربع ويندوز XP مع سيغوين. ومع ذلك، الآن أنا بحاجة للحصول عليه للعمل على Win32 أصلا.

والجزء الصعب هو أن بلدي popen2 يستخدم شوكة () وexecl () لبدء عملية وتعيين تيارات لستدين والمعياري للعمليات طفل. هل هناك طريقة نظيفة أستطيع أن أفعل ذلك في ويندوز؟ في الأساس، وأود أن إنشاء popen2 الذي يعمل في ويندوز بنفس طريقة نسختي يونكس. بهذه الطريقة فقط ويندوز رمز معين سيكون في تلك الوظيفة وأنا لا يمكن أن تفلت من كل شيء يعمل آخر بنفس الطريقة.

وأي أفكار؟

وشكرا!

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

المحلول

في ويندوز، يمكنك استدعاء CreatePipe أولا (على غرار الأنابيب (2))، ثم CreateProcess. الخدعة هنا هو أن CreateProcess يحتوي على معلمة حيث يمكنك تمرير ستدين، المعياري، ستدير العملية التي تم إنشاؤها حديثا.

لاحظ أنه عند استخدام stdio، ما عليك القيام به fdopen لإنشاء الكائن الملف بعد ذلك، والتي تتوقع أرقام الملفات. في مايكروسوفت CRT، أرقام الملفات تختلف عن مؤشرات الملفات OS. ذلك أن يعود الطرف الآخر من CreatePipe إلى المتصل، عليك أولا _open_osfhandle للحصول على رقم ملف CRT، ثم fdopen على ذلك.

إذا كنت تريد أن ترى كود العمل، وتحقق من _PyPopen في

http://svn.python.org /view/python/trunk/Modules/posixmodule.c؟view=markup

نصائح أخرى

وأعتقد أنك قد حقق بداية جيدة جدا لمشكلتك باستخدام الدالة () popen2 إلى مجردة بعيدا عن القضايا عبر منصة. كنت أتوقع أن يأتي وتشير "مآخذ"، ولكن أنا متأكد من أن هذا ليس ذات الصلة بعد قراءة السؤال. هل يمكن استخدام مآخذ بدلا من الأنابيب - انها تكون مخفية في وظيفة popen2 ()

وأنا 99٪ متأكد من أنك يمكن تنفيذ الوظيفة المطلوبة على ويندوز، وذلك باستخدام ويندوز واجهات برمجة التطبيقات. ما لا أستطيع فعله هو نقطة لك وظائف الصحيحة بشكل موثوق. ومع ذلك، يجب عليك أن تدرك أن مايكروسوفت لديها أكثر من المكالمات API POSIX مثل المتاحة، ولكن مسبوقة الاسم مع '_'. وهناك أيضا المكالمات API الأم التي تحقق آثار fork وexec.

وتعليقاتك تشير إلى أن كنت على بينة من القضايا مع توافر البيانات والمآزق المحتملة - توخي الحذر

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