LINUX.ORG.RU

Как теперь в функции MyClass::threadFunc() получить указатель на поток, который её вызвал?

Любопытно для чего это понадобилось.

DarkEld3r ★★★★★
()
Ответ на: комментарий от grondek

вторым параметром не получается...

std::thread *thr = new std::thread(&MyClass::threadFunc, this);

как сюда засунуть thr, если он одновременно создаётся...

sitev_ru
() автор топика

Для потоков нету аналога getppid(), только если передавать через аргументы, или как-то ещё. А зачем это тебе?

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от sitev_ru

А, так тебе на thr надо указатель? Тогда присоединяюсь к DarkEld3r: нафига?

grondek
()
Последнее исправление: grondek (всего исправлений: 1)
Ответ на: комментарий от sitev_ru

Или ты хочешь рулить потоком из функции которая в нем выполняется? Хреновая идея.

Shadow1251
()
Ответ на: комментарий от sitev_ru

Сначала объяви указатель, а при создании передай в функцию ссылку на указатель или указатель на указатель.

four_str_sam
()
Ответ на: комментарий от sitev_ru

А прямо тут запомнить никак? Ты же в этом же объекте MyClass находишься.

grondek
()

ну, можно изнутри вызвать
this_thread::get_id();
и по этому id'у из какого-нибудь мапа получить указатель. но предварительно нужно в мап засунуть указатель и его id, получив его через thr->get_id()

Iron_Bug ★★★★★
()
Ответ на: комментарий от sitev_ru

чтобы чистить его из списка главного объекта...

Чистить - это в смысле delete позвать? Может тебе подойдёт создавать обьект потока на стеке и потом звать detach?

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

может быть сделать по-другому:

std::thread *thr = new std::thread(&WebServer2::threadStep, this, socket); lstThread.push_back(thr);

добавили в список потоков...

и теперь ниже пробегать по списку lstThread и проверять, завершилось выполнение потока или нет?

кстати, как проверить завершение потока?

sitev_ru
() автор топика
Ответ на: комментарий от sitev_ru

кстати, как проверить завершение потока?

joinable. А проверять надо только с целью удаления? Если да, то я бы всё-таки detach рекомендовал.

DarkEld3r ★★★★★
()
Ответ на: комментарий от asaw

joinable будет true даже если поток ещё считается.

А не наоборот? Будет true если завершился, но join не позвали. Но да, я был не прав.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

joinable будет true если завершился, но не был ещё joined, либо если ещё не завершился.

asaw ★★★★★
()

ТС, ты на вопрос почему не отвечаешь? Зачем тебе понадобилось ломать API, которой специально сделан так, чтобы у тебя не возникало желания его ломать? Что ты за велосипед такой хочешь изобразить, который по твоему мнению ещё не придумали?

asaw ★★★★★
()

Можно функции потока передать указатель на пустой промежуточный обьект, а потом в этот обьект поместить указатель на поток, лучше всего weak_ptr плюс shared_ptr в создающем поток потоке.

quiet_readonly ★★★★
()
Ответ на: комментарий от quiet_readonly

Но зачем это делать, если разработчики библиотеки довольно прозрачно намекнули, что этого делать не нужно?

asaw ★★★★★
()

Из любого места же можно узнать TID и по нему же получить указатель. Ну и конечно, если тред отдетачен, можно проверить не завершился ли он отправив ему нулевой сигнал через pthread_kill() (или как оно там) — если ответит, значит еще жив.

Мы же про POSIX треды, да?

deep-purple ★★★★★
()

указатель на переменную + блокировка потока до инициализации?

Tanger ★★★★★
()
Ответ на: комментарий от deep-purple

Зачем там std:: в таком случае? Просто потоки нужно проектировать так, чтобы не было необходимости посылать позиксовые сигналы.

asaw ★★★★★
()
Ответ на: комментарий от deep-purple

зачем?... есть главный класс, который содержит список потоков... нам нужно быть уверенным, что все потоки из списка в конечном итоге завершились... если какой-то поток не завершается, то в будущем анализировать и выявлять причину... значит, кто-то должен удалять этот поток из списка потоков... как это лучше реализовать?

sitev_ru
() автор топика
Ответ на: комментарий от sitev_ru

Ну и как часто ты проверять собрался что поток(и) еще жив(ы)? Хз. Да пусть потоки сами и удаляют и калбяк/эвент завершения дергают.

А главный класс пусть не очень часто смотрит, если какая-то хрень уже давно висит в списке и не сделала себе вдоль, тогда спросить уже сигналом «ты живое?» ну и далее по необходимости, либо оставить жить, либо прибить с очисткой списка.

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Внутри функции, вызванной потоком, сделал:

std::thread::id this_id = std::this_thread::get_id();

this->g_mutex.lock(); int count = lstThread.size(); for (int i = 0; i < count; i++) { std::thread* thr = lstThread; std::thread::id index_id = thr->get_id(); if (index_id == this_id) { lstThread.erase(lstThread.begin() + i); LOGGER_OUT(«THREAD», «Delete thread ...»); break; } } this->g_mutex.unlock();

Тестирую... Вроде пока работает... А как спросить уже сигналом «ты живое?»

sitev_ru
() автор топика
Ответ на: комментарий от sitev_ru

Не знаю как оно в ваших крестах, но полюбому есть же. Вот с чистой си: http://linux.die.net/man/3/pthread_kill

If sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a thread ID

Как я и говорил — можно чекать что он еще жив.

deep-purple ★★★★★
()
Ответ на: комментарий от sitev_ru
#include <iostream>
#include <thread>
#include <forward_list>
#include <atomic>

int main() {
    std::atomic<bool> threadsShouldStop(false);

    std::forward_list<std::thread> threadPool;

    for(int i = 1; i <= 4; i++) {
        threadPool.push_front(std::thread([&]() {
            while(!threadsShouldStop) {
                std::cout << "I am alive!" << std::endl;
            }
        }));
    }

    threadsShouldStop = true;

    for(auto &thread : threadPool) {
        thread.join();
    }

    return 0;
}

ck114
()
Ответ на: комментарий от sitev_ru

В функцию потока передавать указатель на разделяемые данные, в которых перед завершением потока будет устанавливаться флаг, что поток завершен. Но из главного потока нужно будет кроме проверки флага завершения потока делать после этого join к нему. Потому что возможна ситуация, что флаг уже установлен, а оставшиеся после выполнения функции потока операции еще не завершены (разные деструкторы объектов в функции потока, pthread at exit handlers, очистка стека, обработчиков исключений, которые создаются компилятором и другой внутренней кухни библиотеки потоков и OS).

Если ты после создания потока сделаешь detach, то все это не требуется, но нужно как-то гарантировать, что поток завершился с учетом того, что после завершения кода функции потока, также должна отработать куча другого кода, про который я писал выше (я так и не придумал, как это сделать надежно, т.к. одним флагом, который выставляется в потоке перед его завершением вопрос не решается, ибо код поточной функции уже завершился, но еще часть автосгенерированного кода осталась, а он может лежать в свопе, например, или в каком-то деструкторе будет вызываться сброс данных в базу и отключение от нее, а сеть в этот момент отвалилась и ты будешь ждать таймаута, а за это время основной поток уже завершится).

APVS
()

Кстати, немного не по теме. Ты конечно в курсе, что в новых потоках нужно отключать обработку posix сигналов? Все сигналы должны обрабатываться в основном потоке...

APVS
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.