Boost/Wielowątkowość

0

Witam serdecznie.

Pracuję z biblioteką Boost, i wiem mniej więcej na jakiej zasadzie działają tam wątki i jak się je tworzy, ale potrzebuje waszej pomocy. Mam zamiar stworzyć aplikacje serwera do gry, który będzie opierał się na wielu wątkach. Jeden główny będzie odpowiedzialny za samą grę, czyli wszystkie czasowe zdarzenia, interakcje i tak dalej.

Chciałbym zrobić tak, że do każdego połączonego gracza stworzyć wątek który będzie go obsługiwał jego, czyli odbierał i wysyłał dane przez protokół TCP. I tutaj jest właśnie moje pytanie, czy da się tak zrobić, że gdy w wątku nastąpi crash, to nie wyłączy (crashuje) to mojej całej aplikacji?

Dziękuje z góry za wasze odpowiedzi,
Pozdrawiam!

0

Co to znaczy "crash" w wątku? o_O Łapiesz wyjątki, obsługujesz blędy i piszesz porządny kod to nie ma "crashów".

1

To nie jest dobry pomysł. Jeżeli coś się wysypało (np. dereferencja wskaźnika, który wskazuje na pamięć, do której nie masz dostępu) i nie udało ci się złapać wyjątku to zdecydowanie najlepszą decyzją jest natychmiastowe wyjście z aplikacji. Jeżeli nie wiesz co konkretnie się wydarzyło - a nie wiesz, bo nie złapałeś i nie obsłużyłeś wyjątku - to nie pozwalasz błędowi się propagować, bo masz wtedy szansę na całą gamę undefined behaviours zaczynając od "nic złego się nie stało" po możliwość wybuchu komputera.

0

Odnośnie oryginalnego pytania:

Jak koledzy mówili, generalnie nie da się. Można próbować łapać SIGSEGV, ale tylko po to, aby ewentualnie spróbować zapisać stan gry (a nuż się jeszcze uda), grzecznie przeprosić użytkownika za awarię i wyjść. Ale trzeba pisać tak, żeby do tego nie dopuścić. Łapanie SIGSEGV to nie jest normalny sposób obsługi błędów.

Natomiast takie zachowanie mógłbyś uzyskać w środowiskach zarządzanych (np. Java / .NET) - tam raczej trudno "skraszować" aplikację inaczej niż niewyłapanym wyjątkiem, a w 99% przypadków wyłapanie wyjątku pozwala kontynuować pracę.

0

Na Windowsie się da przez np. przez SEHa - i to nie jest żaden hak. Można nawet łapać systemowe wyjątki zwykłym try catchem (po ustawieniu odpowiednich opcji w VC++).
Na Linuksie też się da przez łapanie SIGSEGVa i long jumpa ale to raczej hak. Możliwe, że są tam jakieś lepsze sposoby ale dawno nie używałem linuksa ;p.

0

od kiedy C++ rzuca wyjątkiem przy dereferencji nieprawidłowego wskaźnika? taka dereferencja kończy się SIGSEGV a nie wyjątkiem

#include <iostream>
using namespace std;

int main()
{
    int *zero = nullptr;

    try
    {
        *zero = 3;
    }
    catch (...)
    {
        cout << "kupa" << endl;
    }
}
c:\pp\myprogs\cpp>cl ex.cpp /EHa
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.319 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

ex.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:ex.exe
ex.obj

c:\pp\myprogs\cpp>ex
kupa

c:\pp\myprogs\cpp>
0

Oj, no i rozpętała się burza po moim zbyt niejasnym skrócie myślowym. Także poprawię się: gdy nastąpi błąd, który możemy przechwycić: sygnał, który go.. sygnalizuje czy wyjątek.

0

IMHO ignorowanie segfaultow jest dozwolone w przypadkach:

  1. Korzystasz z zewnętrznej biblioteki, która sypie segfaultami nie wiadomo kiedy i nie wiadomo dlaczego i nie możesz jej zmienić na inną
  2. Twoja aplikacja nie ma prawa się zcrashować bo np. steruje reaktorem ktory wybuchnie jezeli pojdzie segfault ;)
  3. Niskopoziomowe wymagania systemowe - przykładowo w sterownikach często trzeba w __try __except zwalidować pamięć przekazanę przez użytkownika.

1 użytkowników online, w tym zalogowanych: 0, gości: 1