ZeroMQ Kill Thread nie działa

ZeroMQ Kill Thread nie działa
DR
  • Rejestracja:prawie 13 lat
  • Ostatnio:ponad 10 lat
  • Postów:13
0

Siemka
Tworzę projekt z użyciem ZeroMQ i mam taki problem. Potrzebuję funkcji do startowania i ubijania dodatkowego wątku. Jak Start działa ok tak ze stopem są problemy. Poniżej kod:

Kopiuj
 

private Thread _workerThread;
private object _locker = new object();
private bool _stop = false;

public void Start()
        {
            _workerThread = new Thread(RunZeroMqServer);
            _workerThread.Start();
        }

public void Stop()
        {
            lock (_locker)
            {
                _stop = true;
            }

            _workerThread.Join();
            Console.WriteLine(_workerThread.ThreadState);
        }

Gdzieś w internecie znalazłem też coś takiego:

Kopiuj
 

void AsyncZmqListener::Stop()
{
    _stopped = true;
    delete _zmqContext;             // <-- Crashes the application. Changing to 'zmq_term(_zmqContext)' does not terminate recv()
    pthread_join(_thread, NULL);    // <-- This waits forever
}

ale właśnie tak jak jest napisane w komentarzach, nie działa to.

Ma ktoś może jakiś pomysł na tą funkcję stopa?

szogun1987
  • Rejestracja:ponad 19 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Lublin/Gdynia
0

Mógłbyś pokazać metodę RunZeroMqServer?


szogun
DR
  • Rejestracja:prawie 13 lat
  • Ostatnio:ponad 10 lat
  • Postów:13
0

Jasne

Kopiuj
 

private void RunZeroMqServer()
        {
            using (var context = ZmqContext.Create())
            using (ZmqSocket server = context.CreateSocket(SocketType.REP))
            {
                /*
                var bindingAddress = new StringBuilder("tcp://");
                bindingAddress.Append(_ipAddress);
                bindingAddress.Append(":");
                bindingAddress.Append(_port);
                server.Bind(bindingAddress.ToString());
                */

                //server.Bind("tcp://192.168.0.102:50000");
                server.Bind("tcp://*:12345");

                while (!_stop)
                {
                    string message = server.Receive(Encoding.Unicode);
                    if (message == null) continue;

                    var response = ProcessMessage(message);
                    server.Send(response, Encoding.Unicode);

                    Thread.Sleep(100);
                }
            }
        }

private string ProcessMessage(string message)
        {
            ServiceRepositoryMessage srm = JsonConvert.DeserializeObject<ServiceRepositoryMessage>(message);
            string response = "";

            switch (srm.FunctionName)
            {
                case "registerService":
                    registerService(srm.ServiceName, srm.ServiceAddress, srm.BindingType);
                    return response = srm.ServiceName + " on " + srm.ServiceAddress + " using a " + srm.BindingType + " protocol was registered!";
                case "unregisterService":
                    unregisterService(srm.ServiceName);
                    return response = srm.ServiceName + " was unregistered";
                case "getServiceAddress":
                    return response = getServiceAddress(srm.ServiceName, srm.BindingType);
                case "isAlive":
                    isAlive(srm.ServiceName);
                    return response = srm.ServiceName + " is alive and kicking!";
                default:
                    return response = "Wrong service name, the only acceptable names are: registerService, unregisterService, getServiceAddress, isAlive";
            }
        }

Funkcje registerService itp. to są już funkcję operujące na bazach danych, dodające do bazy adres serwisu który się połączy z moim itd

szogun1987
  • Rejestracja:ponad 19 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Lublin/Gdynia
0

Na początek pole _stop to że odwołujesz się do tej samej zmiennej nie znaczy że odwołujesz się do tego samego obszaru pamięci procesory i kompilatory robią wiele optymalizacji.
Poczytaj o Thread.MemoryBarrier i volatile


szogun
wedlock
  • Rejestracja:prawie 13 lat
  • Ostatnio:prawie 4 lata
  • Lokalizacja:Bartoszyce
  • Postów:180
0

zamiast

Kopiuj
Thread 
``` używaj Task ``` ``` ( zalecane przez M$ ). Klasa Task jako jeden z parametrów konstruktora przyjmuje CancelationTokenSource. Ustawiasz ten token na .cancel a w tasku w bloku Try/Catch sprawdzasz status tego tokena i w momencie gdy token ustawi się na ThrowIfCancelationRequested ( piszę z pamięci więc mogę pomylić się w nazewnictwie ) rzucany jest wyjątek a ty po prostu w Finally obsługujesz go i kończysz Task. Sprawdź czy konstruktor Task przyjmuje ten token. Jest on raczej używany do "odpal i zapomnij". Natomiast Task<t> ``` ``` na pewno jako jeden z parametrów przyjmuje token.

Możesz też użyć Backgroundworker który bazuje na Task/Thread i sam z siebie wspiera zatrzymanie pracy z podaniem wyniku tej pracy.

edytowany 1x, ostatnio: wedlock
szogun1987
  • Rejestracja:ponad 19 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Lublin/Gdynia
0

Akurat w tym przypadku wątek może okazać się lepszym rozwiązaniem od Taska. Task jest przeznaczony dla zadań które trwają kilka do kilkudziesięciu sekund w ten sposób wątek jest zwracany do puli wątków i może zostać wykorzystany ponownie. Jeżeli metoda wywoływana w Tasku będzie trwała wiele minut albo godzin, a w międzyczasie inne elementy kodu będą uruchamiać inne zadania może się okazać, że pula wątków za bardzo się rozrośnie (zwłaszcza gdy takich dużych zadań będzie kilka). A CancelationTokenSource działa też na wątkach.


szogun
wedlock
  • Rejestracja:prawie 13 lat
  • Ostatnio:prawie 4 lata
  • Lokalizacja:Bartoszyce
  • Postów:180
0

Pozwolę sobie nie zgodzić się z tobą.

szogun1987 napisał(a):

Akurat w tym przypadku wątek może okazać się lepszym rozwiązaniem od Taska. Task jest przeznaczony dla zadań które trwają kilka do kilkudziesięciu sekund w ten sposób wątek jest zwracany do puli wątków i może zostać wykorzystany ponownie.

A skąd ta wiedza. Ja czytając o Taskach wyczytałem jedynie, że jest to następca klasy Thread i korzystanie z tego ma zapewnić kompatybilność dla programu w przyszłości po wycofaniu klasy Thread. Zresztą pod skórą Task-a i tak siedzą niektóre metody i mechanizmy z Thread-a. Nigdzie nie czytałem o takim podziale tych klas.

szogun1987 napisał(a):

Jeżeli metoda wywoływana w Tasku będzie trwała wiele minut albo godzin, a w międzyczasie inne elementy kodu będą uruchamiać inne zadania może się okazać, że pula wątków za bardzo się rozrośnie (zwłaszcza gdy takich dużych zadań będzie kilka).

Jeśli przekroczysz pulę wątków to i Taski się zblokują . Natomiast zadania będą wykonywane w kolejce bo czekają na swoją kolej w sposób podobny do SpinWait. Oczywiście czas wykonania będzie olbżymi ale .... jak chciał programista tak ma.

Skoro Task ma wykonywać się długo to przy tworzeniu proszę podać mu Schedulera z parametrem LongRunningTask.

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 7 godzin
  • Lokalizacja:Wrocław
0
wedlock napisał(a):

Ja czytając o Taskach wyczytałem jedynie, że jest to następca klasy Thread i korzystanie z tego ma zapewnić kompatybilność dla programu w przyszłości po wycofaniu klasy Thread. Zresztą pod skórą Task-a i tak siedzą niektóre metody i mechanizmy z Thread-a. Nigdzie nie czytałem o takim podziale tych klas.

A gdzie to przeczytałeś?
Task to właściwie takie opakowanie na ThreadPool, trudno to nazwać następcą Thread, bo cel trochę inny. Wycofanie klasy Thread?! Kto, kiedy i po co miałby to robić?

wedlock
  • Rejestracja:prawie 13 lat
  • Ostatnio:prawie 4 lata
  • Lokalizacja:Bartoszyce
  • Postów:180
0

a tu : http://helion.pl/ksiazki/programowanie-rownolegle-i-asynchroniczne-w-c-5-0-mateusz-warczak-jacek-matulewski-rafal-pawlaszek,proch5.htm

autorzy książki sugerują, że Task jest "następcą" Thread bo nowinki języka 4.5 zmierzają do większego zastosowania async/await tak aby kod był przejrzysty tak jak by napisany synchronicznie. Sugerują tym, że taka jest polityka M$ i w tym kierunku zmierza język C#.

edytowany 1x, ostatnio: wedlock
somekind
Ok, przynajmniej wiadomo, do jakiej książki nie warto zaglądać.
n0name_l
A to nie bylo przypadkiem, ze jest nastepca w kontekscie "Odpal i kiedys wroc"? Podaj strone.
szogun1987
  • Rejestracja:ponad 19 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Lublin/Gdynia
1

Klasa Task jest lepszym rozwiązaniem w przypadku gdy zadanie ma nie blokować interfejsu użytkownika albo jak w przypadku asynchronicznych akcji w kontrolerze ma za zadanie odciążyć pulę wątków zajmującą się przetwarzaniem wywołań. Możliwość korzystania z async i await też przemawia za tym żeby myśleć o Task'u zanim się pomyśli o wątku. Klasy Thread podobno nie ma w aplikacjach Windows Store (nie pisałem tych aplikacji więc nie wiem), ale z .Net jako takiego nie zostanie wyrzucona z wielu względów. Głównie przez wsteczną kompatybilność oraz fakt że zachowanie puli wątków nie zawsze jest zgodne z intencjami programistów - tych zaawansowanych.
Co do rozrostu puli wątków to z tego co pamiętam (ale mogę się mylić) jedna z jej implementacji podwaja ilość wątków gdy te się wyczerpią, respektując przy tym tylko metodę ThreadPool.SetMaxThreads.


szogun
n0name_l
zachowanie puli wątków nie zawsze jest zgodne z intencjami programistów - tych zaawansowanych., co ma tu zaawansowanie do rzeczy? O.o
szogun1987
Chodzi mi o to że początkujący nie koniecznie potrafią ubrać swoje intencje w słowa a tym bardziej w kod i w ich przypadku nawet gdy pula wątków nie jest najwydajniejsza, albo zanieczyszcza kod bardziej niż wątki to i tak powinni z niej skorzystać.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)