783. thread::id reuse

Section: 33.3.2.1 [thread.thread.id] Status: CD1 Submitter: Hans Boehm Opened: 2008-02-01 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [thread.thread.id].

View all issues with CD1 status.

Discussion:

The current working paper (N2497, integrated just before Bellevue) is not completely clear whether a given thread::id value may be reused once a thread has exited and has been joined or detached. Posix allows thread ids (pthread_t values) to be reused in this case. Although it is not completely clear whether this originally was the right decision, it is clearly the established practice, and we believe it was always the intent of the C++ threads API to follow Posix and allow this. Howard Hinnant's example implementation implicitly relies on allowing reuse of ids, since it uses Posix thread ids directly.

It is important to be clear on this point, since it the reuse of thread ids often requires extra care in client code, which would not be necessary if thread ids were unique across all time. For example, a hash table indexed by thread id may have to be careful not to associate data values from an old thread with a new one that happens to reuse the id. Simply removing the old entry after joining a thread may not be sufficient, if it creates a visible window between the join and removal during which a new thread with the same id could have been created and added to the table.

[ post Bellevue Peter adds: ]

There is a real issue with thread::id reuse, but I urge the LWG to reconsider fixing this by disallowing reuse, rather than explicitly allowing it. Dealing with thread id reuse is an incredibly painful exercise that would just force the world to reimplement a non-conflicting thread::id over and over.

In addition, it would be nice if a thread::id could be manipulated atomically in a lock-free manner, as motivated by the recursive lock example:

http://www.decadent.org.uk/pipermail/cpp-threads/2006-August/001091.html

Proposed resolution:

Add a sentence to 33.3.2.1 [thread.thread.id]/p1:

An object of type thread::id provides a unique identifier for each thread of execution and a single distinct value for all thread objects that do not represent a thread of execution ([thread.threads.class]). Each thread of execution has a thread::id that is not equal to the thread::id of other threads of execution and that is not equal to the thread::id of std::thread objects that do not represent threads of execution. The library may reuse the value of a thread::id of a terminated thread that can no longer be joined.