"Wyłącz widelec" zabija nie tylko procesy uruchomione przez twój fork ... join_any, ale także wszelkie inne procesy, które są potomkami tego samego procesu, który wykonuje disable-fork. Jeśli uruchomiłeś jakiekolwiek inne procesy (używając, na przykład, fork ... join_none) wcześniej w życiu tego procesu, to te inne procesy również zostaną zabite.
Możesz raczej łatwo się przed tym zabezpieczyć, powodując, że widelec ... join_any i jego późniejszy wyłącznik-fork, uruchamia się w nowym procesie potomnym. Ogranicza to efekt twojego wyłączenia-widelca, dzięki czemu może wpływać tylko na nowo uruchomione procesy, na których Ci zależy, i nie ma żadnych innych niepożądanych efektów.
Czy to załączając cały bałagan w „widelec zacząć ... koniec join” tak:
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
Jest to dobrze znany problem z widelcem ... join_any i widelcem ... join_none . Zostało to ostatnio omówione na forum Weryfikacja Gildii i jest opisane w rozdziałach # 79 i # 80 książki Sutherland and Mills "Verilog and SystemVerilog Gotchas".
Umieszczanie "początku wideł" i "łączenia końcowego" na pojedynczych liniach jest niezwykłe, ale podoba mi się to jako sposób na to, aby było oczywiste, że synchronicznie synchronizuję dokładnie jeden proces potomny. Normalnie byłoby to bezużyteczne, ale w tej sytuacji jest to niezbędne.
Ten idiom jest tak powszechne, a więc łatwo dostać się źle, że może wolisz ująć ją w parę makr (nie lubię tego, ale ...):
`define BEGIN_FIRST_OF fork begin fork
`define END_FIRST_OF join_any disable fork; end join
teraz można napisać ...
`BEGIN_FIRST_OF
apply_input();
update_status();
verify_status();
`END_FIRST_OF
gdzie nazwy „... FIRST_OF” mają odzwierciedlać podobieństwo do Specman (e) konstruktem językowym, który robi to samo.
Może to zmienić się w nieprzydatne pytanie: nie zwolniłem semafora po wyłączeniu widelca, który nie spowodowałby kolejnych transakcji. Aktualnie debuguję zaktualizuję później – wisemonkey
Co próbujesz osiągnąć? Czy na pewno potrzebujesz tutaj bloku równoległego? –
Dzięki @ Adam12 tak te bloki muszą być równoległe, tak jak potrzebuję weryfikacji funkcjonalności. Próbuję zweryfikować, czy odczyt podczas aktualizacji do danego rejestru w toku daje prawidłowe dane. I tak, problem polegał na tym, że nie wydawałem semafora. Rozwiązałem go i teraz działa poprawnie – wisemonkey