2013-11-25 5 views
5

मैं Windows एक पर्ल स्क्रिप्ट है कि एक निष्पादन कॉल चल रहा है में हूँ बाहर निकलने नहीं दुभाषिया:पर्ल कमांड लाइन

$command = "$path_to_exe -i $dir -o $results"; 
my $pid = fork(); 

    if (!$pid) { 
     system($command); 

     #do stuff 

    } else { 
     #do stuff 
    } 

print "Exiting..." 
exit; 

इसके बजाय के बाद बाहर निकलने की, perl.exe सिर्फ idles। एक पॉप-अप तो मुझे बताता है कि "पर्ल कमांड लाइन दुभाषिया ने काम करना बंद कर दिया है।"

मैं Windows में प्रक्रिया प्रबंधन के बारे में बहुत ज्यादा नहीं पता है, और मैं इस मंच कि यह fork() और exec() उपयोग करने के लिए अच्छा अभ्यास नहीं है पर पहले से पढ़ लिया है, लेकिन कोड दुभाषिया के अलावा अच्छी तरह से काम करता है भाग को बंद नहीं। मैंने यूनिक्स में प्रोग्राम को लागू करने की कोशिश करने से सबकुछ करने की कोशिश की है (जो एक ही त्रुटि देता है) Win32::Process कमांड का उपयोग करने के लिए - लेकिन कुछ भी काम नहीं करता है। मुझे उम्मीद थी कि एक आसान समाधान हो सकता है जो मुझे पहले से लिखे गए कार्यों को संरक्षित करने की अनुमति देगा।

अगर कोई यह बता सकता है कि यह कोड चलाए जाने पर विंडोज में वास्तव में क्या हो रहा है, तो यह भी मददगार होगा!

+0

कांटा-कार्यकारी जीत पर अच्छा अभ्यास है, क्योंकि जीत इसे करने के लिए अनुकूल नहीं है नहीं है। विन भारी थ्रेडिंग और स्थानीय आरपीसी अनुकूलित करने के लिए है। लेकिन आपके मामले में यह वास्तविक समस्या नहीं है, क्योंकि आपके लिए वास्तव में महत्वपूर्ण नहीं है, कि आपकी रैपर स्क्रिप्ट 0.001s या 0.01s ओवरहेड उत्पन्न करती है। यह केवल महत्वपूर्ण था, यदि आपके उदाहरण के लिए डेटाबेस सर्वर डिमन या कुछ ऐसा था जिसे प्रति सेकंड हजार बार कहा जाना चाहिए। एक और बात, कि हाँ, कांटा() - exec() धीमा है, लेकिन कांटा() - सिस्टम() भी धीमा है ... मैं आगे देखता हूं, कि आपने मेरी दूसरी समस्या ($ pid और $$ नहीं)। आपको सहकारी होना चाहिए। – peterh

उत्तर

4

मैं 2 स्वतंत्र समस्याएं देख सकता हूं।

  1. system() एक बच्चे की प्रक्रिया बनाता है, इस प्रकार यदि आप फोन एक system() एक काँटेदार बच्चे से, आप 3 प्रक्रियाओं होगा। लेकिन आप केवल दूसरे (कांटेदार बच्चे) को मारते हैं, और बच्चे के बच्चे ($ कमांड) नहीं। exec() जैसे कुछ फ़ंक्शन का उपयोग करने का प्रयास करें, यूनिक्स पर यह वास्तविक प्रक्रिया के स्थान (और पिड पर) पर बाल प्रक्रिया शुरू करता है। यदि आपके पास भाग्य है, तो विंडोज़ पर पर्ल वही करता है।

  2. पैरेंट थ्रेड में आप $$ को मारते हैं, जो वर्तमान प्रक्रिया है। शायद आप $pid (जो पैरेंट थ्रेड पर बाल प्रक्रिया का ढक्कन है) को मारना चाहते थे।

+0

मैंने exec() के साथ प्रयोग किया, और मैंने पाया कि यह भी बाहर नहीं निकलता है। मैं फिर से कोशिश करूंगा और देखें कि क्या होता है।विंडोज़ में '$ pid' बाल प्रक्रिया का' $ pid' नहीं है, यह एक नकारात्मक संख्या है, जो मुझे लगता है, "छद्मप्रोसेस" से मेल खाता है। किसी भी तरह, जिस तरह से मैंने 'टास्ककिल' का उपयोग किया है वह कार्यात्मक है, मुझे मत पूछो कि कैसे। धन्यवाद – user86895

+0

मुझे लगता है कि अस्तित्व के लिए आपका रास्ता यह है कि यदि आप अंधेरे शूटिंग को रोकते हैं और अपने हाथों और आंखों के साथ लक्ष्य बनाना शुरू करते हैं। – peterh

1

मैं (कार्यक्रम बाहर यह बार और, सबसे महत्वपूर्ण बात, पर्ल दुभाषिया तोड़ नहीं है!) निम्नलिखित प्रयोग किया है:

use Win32::Job; 
my $job = Win32::Job->new; 

    # Run $command for $max_time 
    $job->spawn($Config{"path/cmd.exe"}, $command); 
    $job->run($max_time); 
    exit; 
1

मेरे मामले में मैं कुछ "उपयोग" बयान हटा दिया और इसे हल किया गया था। ऐसा शायद होता है क्योंकि विंडोज़ पर "कांटा" के लिए perl कार्यान्वयन सही नहीं है और इसमें कुछ "भारी" ऑब्जेक्ट जैसे ओएलई लाइब्रेरी आयात करने में समस्याएं हैं।

सटीक का उपयोग करता है मैं हटाया:

#use Win32::OLE qw(in with); 
#use Win32::OLE::Const 'Microsoft Excel'; 

युक्ति: यदि संभव हो तो, गतिशील पुस्तकालयों बिंदु के बाद आयात की कोशिश कोड बॉक्स में कोई कांटा है। मेरे मामले के लिए

उदाहरण:

# code with fork 
eval "use Win32::OLE::Const 'Microsoft Excel';"; 
eval "use Win32::OLE qw(in with);"; 
# code without fork