Когда именно является деструктором или заканчивается в потоке - PullRequest
0 голосов
/ 06 октября 2019

Я использую C ++ 11 std :: thread. Моя путаница основана на следующем:

terminate() в потоке вызывается, если к нему не вызывается ни join(), ни detach(). Это означает, что когда поток возвращает:

a. , он проверяет, вызван ли join() или detach() для него, если нет, то вызывается terminate() (создает coredump),

b. , если вызывается join(), деструктор потока будет вызван главным (или вызывающим потоком)

c. если detach() был вызван во время выполнения потока, поток не вернется к основному для очистки, вместо этого сам этот поток будет отвечать за вызов своего деструктора

Вопрос: Если приведенные выше пункты были верными, тогда я не понимаю , в какой именно точке было принято решение о прекращении потока или нет на основании того, является ли join() или detach() вызывается или нет?

void function_1()
{
        return;
}
int main()
{
        std::thread t1(function_1);
        std::cout<<"\nFirst Sleep for 5 seconds:\n"; 
        sleep(5);

        cout<<"\n2nd Sleep for 5 seconds:\n";
        sleep(5);

        if(t1.joinable())
        {
                cout<<"\nGonna join()\n";
                t1.detach();
        }
        cout<<"Exiting from main ...\n";

}

Поскольку поток завершит свое выполнение до 5-й секунды, я предположил, что поток должен быть прерван, так как нет join()/detach() до этого момента. Но там нет звонка terminate(). Вместо этого поток успешно отсоединяется.

Однако, если я не отсоединяюсь, терминатор вызывается через 2 сна после "Exiting from main....", прямо перед return 0; Означает ли это, что поток не очищен (его деструктор не вызван), пока основной поток (или вызываемый поток) не вернется?

Это причина, по которой нужно detach(), чтобы очистка потока не ожидала возвращения основного (или вызывающего потока)?

1 Ответ

1 голос
/ 06 октября 2019

Похоже, вы путаете две вещи: объект std::thread и поток выполнения, которым управляет этот объект.

Вызов std::terminate вызван деструктором объекта std::thread, если , то это соединение. Это не имеет прямого отношения к тому, завершил ли выполнение поток выполнения, управляемый объектом std::thread.

В вашем коде деструктор t1 - это то, что вызовет std::terminate. t1 - это обычный объект C ++, здесь локальная переменная main. Он разрушается, когда заканчивается его область - конец основного здесь. Таким образом, вы должны сделать t1 не присоединяемым до основного возврата, либо вызвав join или detach на t1. Независимо от того, закончил ли function_1 выполнение потока выполнения или нет, не имеет значения.

...