2013-01-11 6 views
6

मैं निम्नलिखित छद्म कोड के लिए कुछ इसी तरह है:समुचित उपयोग

for (lets say 10 iterations) 
begin 
// Do some configuration changes 
    fork 
     begin 
     ///apply input to design 
     end 
     begin 
     while (1) 
     /// at particular point update expected status/values 
     end 
     begin 
     while (1) 
     /// read status and verify with expected values 
     end 
    join_any 
end 

कोड से: इनपुट कांटा तोड़ सकते हैं का केवल आवेदन, अन्य 2 धागे के बाद से, जबकि तहत काम कर रहे हैं (1) मैं से प्रत्येक यात्रा के बीच सभी धागे अक्षम करना चाहते हैं यानी एक बार इनपुट की धारा लागू किया जाता है - को निष्क्रिय सभी पैदा धागे जब तक अगले चरण शुरू होता है (नए विन्यास)

तो मैं

.... 
join_any 
disable_fork 
end 
करने के लिए कोड ऊपर संशोधित

हालांकि यह लूप के साथ भी अक्षम है/या ऐसा कुछ जो मुझे समझ में नहीं आता है लेकिन प्रभाव परीक्षण लटका हुआ है। क्या कोई मुझे कारण और समाधान समझा सकता है?

+0

यह एक उपयोगी प्रश्न में बदल सकता है: मैं कांटा को अक्षम करने के बाद सेमाफोर जारी नहीं कर रहा था जिससे कोई और लेनदेन नहीं हुआ। मैं वर्तमान में डीबगिंग कर रहा हूं बाद में – wisemonkey

+0

अपडेट कर रहा हूं आप क्या करने की कोशिश कर रहे हैं? क्या आपको यकीन है कि आपको यहां समानांतर ब्लॉक की आवश्यकता है? –

+0

धन्यवाद @ एडम 12 हाँ इन ब्लॉकों को समानांतर होने की आवश्यकता है, जिस तरह से मुझे कार्यक्षमता को सत्यापित करने की आवश्यकता है। मैं यह सत्यापित करने की कोशिश कर रहा हूं कि प्रगति पर विशेष रजिस्टर में अपडेट करते समय पढ़ा जाए तो वैध डेटा देता है। और हाँ मुद्दा इसलिए था क्योंकि मैं सेमफोर जारी नहीं कर रहा था। मैंने इसे हल कर लिया है और यह ठीक से काम कर रहा है – wisemonkey

उत्तर

18

"अक्षम फोर्क" न केवल आपके फोर्क द्वारा लॉन्च की गई प्रक्रियाओं को मारता है ... join_any, लेकिन किसी अन्य प्रक्रिया जो अक्षम प्रक्रिया के वंशज हैं जो अक्षम-कांटा निष्पादित करते हैं। यदि आपने इस प्रक्रिया के जीवन में पहले किसी अन्य प्रक्रिया को लॉन्च किया है (उदाहरण के लिए, फोर्क ... join_none), तो उन अन्य प्रक्रियाओं को भी मार दिया जाएगा।

आप अपने फोर्क के कारण आसानी से इसकी रक्षा कर सकते हैं ... join_any, और इसके बाद के अक्षम-कांटा, स्वयं की एक नई बाल प्रक्रिया में भाग लेने के लिए। यह आपके अक्षम-कांटा के प्रभाव को सीमित करता है ताकि यह केवल उन नई लॉन्च प्रक्रियाओं को प्रभावित कर सके जिनकी आप परवाह करते हैं, और अन्य कोई अवांछित प्रभाव होने की गारंटी नहीं है।

इस तरह "में शामिल होने कांटा शुरू ... अंत" में पूरी गंदगी संलग्न कर ऐसा करें:

fork begin // isolate the following code as a single child process 
    fork // launch the processes you wish to manage 
    apply_input(); 
    update_status(); 
    verify_status(); 
    join_any // kill off the *_status threads when apply_input terminates 
    disable fork; 
end join // end of child process isolation 

इस के साथ कांटा ... join_any और कांटा ... join_none एक प्रसिद्ध मुद्दा है । हाल ही में सत्यापन गिल्ड फोरम पर चर्चा की गई है, और इसे सुथरलैंड और मिल्स पुस्तक "वेरिलोग और सिस्टम वेरिलोग गॉटचास" की धारा # 79 और # 80 में वर्णित किया गया है।

एकल लाइनों पर "कांटा शुरू करना" और "अंत में शामिल होना" रखना असामान्य है, लेकिन मुझे यह बहुत स्पष्ट बनाने के तरीके के रूप में पसंद है कि मैं सिंक्रनाइज़ रूप से एक बच्चे की प्रक्रिया को मजबूर कर रहा हूं। आम तौर पर यह करने के लिए एक बेकार बात होगी, लेकिन इस स्थिति में यह आवश्यक है।

यह मुहावरा, गलत पाने के लिए इतना आम है, और इसलिए आसान है, आप मैक्रो की एक जोड़ी में यह संपुटित करना पसंद करते हैं कि हो सकता है (मुझे यह पसंद नहीं है, लेकिन ...):

`define BEGIN_FIRST_OF fork begin fork 
`define END_FIRST_OF join_any disable fork; end join 

अब आप लिख सकते हैं ...

`BEGIN_FIRST_OF 
    apply_input(); 
    update_status(); 
    verify_status(); 
`END_FIRST_OF 

जहां नाम "... FIRST_OF" वही चीज़ Specman (ई) भाषा निर्माण करने के लिए समानता को प्रतिबिंबित करना है।

+0

धन्यवाद, यह और अधिक समझ में आता है। अभी तक मेरे परीक्षणों में केवल एक कांटा है इसलिए मेरा दृष्टिकोण काम कर रहा है, लेकिन मैं उन लोगों को बदल रहा हूं जिन्हें आपने भविष्य में बदलावों से अलग करने के लिए प्रस्तावित किया था। और मैं आपसे सहमत हूं, मैं कम से कम परिभाषित नहीं करूँगा जब तक कि मैं उचित पद्धति के लिए उपयोग नहीं करता – wisemonkey

0

अक्षम कांटा ठीक काम करना चाहिए। यहां छोटा उदाहरण दिया गया है।

module top; 

     initial 
     begin 
      $display(" BEFORE fork time = %0t ",$time); 

      for(int i = 0 ; i < 3 ; i++) 
      begin 
      fork 
       automatic int j = i; 
       begin 
        $display(" Action thread started time = %0t j: %0d",$time,j); 
        #(10*j); 
        $display(" Action thread ended time = %0t j: %0d",$time,j); 
       end 

       begin 
       $display(" Entered timeout_15 = %0t j: %0d",$time,j); 
       #15; 
       $display(" Ended timeout_15 = %0t j: %0d",$time,j); 
       end 
      join_any 

      disable fork; // it kills all processes 
      $display("---------------------------------------------------"); 
     end 

     #100; // This is to make sure if there any threads .. 

     $display(" time = %0d Outside the main fork ",$time); 
     $display(" time = %0d After wait fork ",$time); 
     end 
    endmodule 

उत्पादन ::

BEFORE fork time = 0 
Action thread started time = 0 j: 0 
Entered timeout_15 = 0 j: 0 
Action thread ended time = 0 j: 0 
--------------------------------------------------- 
Action thread started time = 0 j: 1 
Entered timeout_15 = 0 j: 1 
Action thread ended time = 10 j: 1 
--------------------------------------------------- 
Action thread started time = 10 j: 2 
Entered timeout_15 = 10 j: 2 
Ended timeout_15 = 25 j: 2 
--------------------------------------------------- 
time = 125 Outside the main fork 
time = 125 After wait fork 
+0

यह अन्य सभी धागे क्यों नहीं मार रहा है? –

0

आप SystemVerilog

process process1; 
process process2; 
fork 
    begin 
    process1 = process::self(); 
    # do something in process 1 
    end 
    begin 
    process2 = process::self(); 
    # do something in process 2 
    end 
join_any 
if (process1 != null && process1.status != process::FINISHED) 
    process1.kill(); 
if (process2 != null && process2.status != process::FINISHED) 
    process2.kill(); 

में प्रक्रियाओं बजाय अक्षम का उपयोग कर उसे निष्क्रिय अधिक सुरक्षित माना जाता है पर विचार करना चाहिए।

संबंधित मुद्दे