Does the definition of a thread in Linux depend on a system call?
1
vote
1
answer
358
views
## Clone
In the manual page for
clone()
/clone3()
system call I find:
> CLONE_THREAD (since Linux 2.4.0).
>
> If CLONE_THREAD is set, the child is placed in the same thread group as the calling process.
> To make the remainder of the discussion of CLONE_THREAD more readable, the term "thread" is used
> to refer to the processes within a thread group.
So, as I understand, from the clone
's perspective, a thread is something that was created with the CLONE_THREAD
flag set (and, thus, ended up in the same thread group as the caller).
## Futex
But looking at, for instance, the manual page for futex()
, I find:
> FUTEX_PRIVATE_FLAG (since Linux 2.6.22)
>
> This option bit can be employed with all futex operations. It tells the kernel that the futex
> is process-private and not shared with another process (i.e., it is being used for synchronization
> only between threads of the same process). This allows the kernel to make some additional
> performance optimizations.
This seems to relate with the definition of clone
, but not quite. When a thread (as in clone is created (that is, the CLONE_THREAD
flag is specified), the created tasks also _have to_ share their VM. However, it is possible to create two tasks which are not threads (as in clone), which would still sharing VM (just specifying CLONE_VM
). But, judging by the [FUTEX : new PRIVATE futexes](https://lwn.net/Articles/229668/) article/patch, the optimization used for _PRIVATE
futexes is that the virtual address of a futex word are used rather than the physical ones, so, one could probably use private futexes in tasks created with CLONE_VM
... but the man for futex()
forbids that.
That is not a critical issue, though: the manual imposes a (seemingly unnecessary) restriction but it doesn't break anything. So, here goes a more thrilling example.
## Close
From the manual for the close()
system call:
> Furthermore, consider the following scenario where two threads
> are performing operations on the same file descriptor:
>
> (1) One thread is blocked in an I/O system call on the
> file descriptor. For example, it is trying
> to write(2) to a pipe that is already full, or trying to read(2) from a stream socket which
> currently has no available data.
>
> (2) Another thread closes the file descriptor.
>
> The behavior in this situation varies across systems.
Clearly, it is assumed here that the two tasks share a file descriptor table, but being threads (as in clone) is neither necessary nor sufficient to claim they do!
If a task is created with CLONE_THREAD|...|CLONE_FILES
, it's all good, but if it's just CLONE_THREAD|...
(which is allowed), the two threads (as in clone) do not share file descriptors, and the tasks cloned with ...|CLONE_FILES
are _not_ threads but _do_ share file descriptors!
## Question
First of all, is this (at least the close()
example) a bug in the manual? Is it because it was written before the clone()
system call was designed? Or am I missing something?
In general: when using a particular system call that has the term "thread" used in its manual, how do I tell what's implied?
In particular (assuming I want to write code that will work on future kernel versions): would it be ok to use private futexes in tasks that share VM but are not threads (as in clone)? Would it be ok thread-safe to call close
in threads (as in clone) that do _not_ share file descriptor tables, as the common sense suggests?
Asked by Kolay.Ne
(170 rep)
Jul 22, 2023, 08:57 AM
Last activity: Jul 22, 2023, 08:22 PM
Last activity: Jul 22, 2023, 08:22 PM