Title
Unclear thread::id specification
Status
nad
Section
[thread.thread.id]
Submitter
INCITS

Created on 2010-08-25.00:00:00 last changed 160 months ago

Messages

Date: 2011-02-11.00:00:00

[ 2011-02-11 Reflector discussion ]

Moved to Tentatively NAD after 5 votes.

Date: 2010-11-22.00:00:00

[ 2010-11-22 Howard Hinnant observes ]

A thread can either be running or terminated. Additionally a thread can be joined, detached, or neither. These combine into the five possible states shown in this table:

RunningTerminated
Neither joined nor detachedshall not reuse idshall not reuse id
detachedshall not reuse idmay reuse id
joinedimpossible statemay reuse id

Only if a thread is neither joined nor detached can it be joined. Or said differently, if a thread has already been joined or detached, then it can not be joined. The sentence:

The library may reuse the value of a thread::id of a terminated thread that can no longer be joined.

precisely defines the two states shown in the above table where a thread::id may be reused.

The following program illustrates all of the possibilities:

#include <mutex>
#include <thread>
#include <iostream>
#include <chrono>

std::mutex mut;

void f()
{
   std::lock_guard<std::mutex> _(mut);
   std::cout << "f id = " << std::this_thread::get_id() << " terminating\n";
}

void g()
{
   std::lock_guard<std::mutex> _(mut);
   std::cout << "g id = " << std::this_thread::get_id() << " terminating\n";
}

int main()
{
   std::cout << "main id = " << std::this_thread::get_id() << "\n";
   std::thread t1(f);
   std::thread(g).detach();
   std::this_thread::sleep_for(std::chrono::seconds(1));
   std::cout << "g's thread::id can be reused here because g has terminated and is detached.\n";
   std::cout << "f's thread::id can't be reused here because f has terminated but is still joinable.\n";
   std::cout << "f id = " << t1.get_id() << "\n";
   t1.join();
   std::cout << "f's thread::id can be reused here because f has terminated and is joined.\n";
   std::cout << "f id = " << t1.get_id() << "\n";
}

main id = 0x7fff71197ca0
f id = 0x100381000 terminating
g id = 0x100581000 terminating
g's thread::id can be reused here because g has terminated and is detached.
f's thread::id can't be reused here because f has terminated but is still joinable.
f id = 0x100381000
f's thread::id can be reused here because f has terminated and is joined.
f id = 0x0
Date: 2010-11-01.19:24:04

[ Resolution proposed by ballot comment: ]

Require a unique thread::id for every thread that is (1) detached and not terminated or (2) has an associated std::thread object.

Date: 2010-10-24.16:08:33

Addresses US-184

It is unclear when a thread::id ceases to be meaningful. The sentence "The library may reuse the value of a thread::id of a terminated thread that can no longer be joined." implies that some terminated threads can be joined. It says nothing about detached threads.

History
Date User Action Args
2011-02-11 18:04:04adminsetmessages: + msg5481
2011-02-11 18:04:04adminsetstatus: open -> nad
2010-11-23 12:10:24adminsetmessages: + msg5396
2010-11-01 19:24:04adminsetmessages: + msg5242
2010-10-24 16:08:33adminsetmessages: + msg5026
2010-08-25 00:00:00admincreate