Можно ли использовать pthread_exit с функциями noException?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Можно ли использовать pthread_exit с функциями noException?

Сообщение Anonymous »

У меня есть модель, в которой минимальная работа выполняется в основном потоке, а почти вся работа выполняется в рабочих потоках. Я хочу быть уверенным, что основной поток НИКОГДА не умрет и ВСЕГДА возвращается обратно в ОС.
Поскольку вся моя работа происходит в рабочих потоках, я хочу уничтожать рабочие потоки, когда возникает какой-то критический момент. ресурс недоступен. Это позволяет мне эффективно писать код, не обрабатывая повсюду ошибки. Например, мне нужно выделить немного памяти в куче. Для этого я могу вызвать «malloc», но «malloc» может вернуть nullptr, и вместо того, чтобы обрабатывать его каждый раз, когда я хочу выделить память, я просто хочу убить поток. Ниже приведен пример кода

Код: Выделить всё

void BlockMainThread () noexcept; // Wait on a semaphore
void ReleaseMainThread () noexcept; // Release the semaphore

int gExitStatus = 0;
bool gShouldRun = true;

[[noreturn]]
void
KillThread (int pExitStatus) noexcept
{
gExitStatus = pExitStatus;

ReleaseMainThread ();

pthread_exit (nullptr); // Calls __forced_unwind internally
}

void *
Malloc (int pSize) noexcept
{
void * ptr = malloc (pSize);

if (!ptr)
KillThread (1);

return ptr;
}

void *
ThreadFunc (void *) noexcept // Executed by ALL worker threads
{
printf ("Thread Started\n");

while (gShouldRun) { // Do work till time to exit

char * ptr = (char *) Malloc (100000);

// Operate on ptr without needing to worry about ptr being NULL

free (ptr);
}

return nullptr;
}

int
main ()
{
pthread_t tid1;
pthread_t tid2; // And so on

pthread_create (&tid1, nullptr, ThreadFunc, nullptr); // And so on

BlockMainThread ();

gShouldRun = false; // Stop the loop on which threads are spinning

pthread_join (tid1, nullptr); // Join with all threads

if (gExitStatus == 0) // All was good
return 0;

// Else log a message depending on the gExitStatus

printf ("Something went wrong");

return gExitStatus;
}
Все функции помечены как noException, что означает, что ни одна из функций никогда не должна выполнять бросок. В противном случае будет вызван std::terminate, что не позволит основному потоку вернуться (чего, как было сказано ранее, я НЕ хочу).
Однако pthread_exit означает бросок исключения 'abi::__forced_unwind'. И это исключение — это то, что необходимо повторно выбросить, если оно будет обнаружено (следовательно, нет смысла его перехватывать). И из-за этого вызывается std::terminate (поскольку мои функции — noException). Это не позволяет основному потоку регистрировать, что пошло не так.
Если функции НЕ отмечены параметром noException, поток завершается, и основной поток продолжит работу, как ожидалось.
Это происходит только в ОС Linux. Один и тот же код НЕ выдает исключение при использовании в ядре Apple и Android.
Вопросы:
  • Есть ли что-нибудь Могу ли я предотвратить std::terminate при вызове pthread_exit внутри функции noException?
  • Могу ли я вообще использовать noException, если хочу использовать эту модель?
  • Существуют ли какие-либо обходные пути для Linux, позволяющие имитировать поведение Apple и Android для конкретных платформ?
Контекст и соображения:
[*]Различия платформ: В Linux pthread_exit использует __forced_unwind для раскручивания и очистки стека, что вызывает исключение. Это не относится к Apple и Android, где pthread_exit не предполагает выдачу исключений.
[*]Обработка исключений: исключение __forced_unwind является особенным и должно распространяться через кадры стека, не будучи перехваченным, поскольку оно перехватывается. и отказ от повторного создания может привести к неопределенному поведению.
[*]Управление ресурсами: цель состоит в том, чтобы аккуратно завершить рабочие потоки, не усложняя обработку ошибок в каждом распределении или критическом разделе.


Подробнее здесь: https://stackoverflow.com/questions/787 ... -functions
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»