Как создать новый поток и прекратить его через некоторое время? - PullRequest
1 голос
/ 12 декабря 2011

Сделка такова:

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

И когда этот поток завершился успешно, я хотел бы иметь возможность изменить некоторую глобальную переменную, в которой могут быть некоторые данные,например, список файлов, например.Вот почему я не могу просто выполнить внешний исполняемый файл из Windows, так как не могу получить доступ к переменным внутри функции, которая была выполнена в новом потоке.

Редактировать: Уточнил проблему намного больше.

Ответы [ 6 ]

3 голосов
/ 12 декабря 2011

Поток уже будет запущен после вызова CreateThread.

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

1 голос
/ 12 декабря 2011

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

Вы не можете уничтожить поток, поскольку уничтожение потока может полностью разрушить некоторые из самых фундаментальных предположений, которые делает программист.Теперь вам нужно будет принять во внимание возможность того, что следующая строка не будет выполняться по причинам, которые вы не можете ни предсказать, ни предотвратить.

Это не похоже на обработку исключений, когда C ++ специально требует вызова деструкторови у вас есть возможность ловить исключения и выполнять специальную очистку.Вы говорите о выполнении одного фрагмента кода, а затем о внезапном завершении выполнения всего этого стека вызовов.Это не сработает.

Причина, по которой веб-браузеры перешли с модели «поток на вкладку» на модель «процесс на вкладку», заключается именно в том, что процессы могут бытьзавершено, не оставляя другие процессы в неизвестном состоянии.Вам нужно использовать процессы вместо потоков.

Когда процесс завершает работу и устанавливает свои данные, вам нужно использовать какую-то систему межпроцессного взаимодействия для чтения этих данных (мне самому нравится Boost.Interprocess).Это не будет выглядеть как обычная глобальная переменная C ++, но у вас не должно возникнуть проблем с ее чтением.Таким образом, вы можете эффективно завершить процесс, если он занимает слишком много времени, и ваша программа останется в разумном состоянии.

1 голос
/ 12 декабря 2011

Ну, вот что делает WaitForSingleObject.Он блокируется до тех пор, пока объект что-то не сделает (в случае потока он ожидает, пока поток не выйдет или не истечет время ожидания).Что вам нужно, это

HANDLE thread = CreateThread(0, 0, do_stuff, NULL, 0, 0);
//rest of code that will run paralelly with your new thread.
WaitForSingleObject(thread, 4000); // wait 4 seconds or for the other thread to exit
0 голосов
/ 12 декабря 2011

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

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

Еще один способ сделать это - поставить в очередь пользовательское задание в рабочий поток, который должен находиться в изменяемом состоянии ожидания . Затем APC может установить некоторую внутреннюю переменную состояния, которая при возобновлении запускает последовательность смерти в потоке.

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

0 голосов
/ 12 декабря 2011

Удалить звонок WaitForSingleObject?

0 голосов
/ 12 декабря 2011

Удалить вызов WaitForSingleObject.Это заставляет ваш родительский поток ждать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...