0

How can a process have a status when only threads are being scheduled (Windows and Linux)?

  1. Let’s say we create process P
  2. Thread T1 is now allocated as well
  3. T1 is now in runnable state
  4. Scheduler picks T1 and set it as runnable alongside with P
  5. New thread T2 is created and marked as runnable
  6. Scheduler picks T2 and give it to another CPU core
  7. T1 now waits for user input and T2 is still running on other other core

What is the state of P blocked/running ?

What is the logic behind any determination of process state?

1 Answer 1

1

Threads do not share the same inheritance properties of traditional processes.

In POSIX at least, threads are considered peers of one another*. When you create a thread from a single process, you've now got two threads T1 and T2, bounded together in the same memory region (and accounting space) in a container called P1.

This can actually lead to confusing behaviour for program designers, in particular when signals arrive as all or any of the threads can receive the signal, not just the first thread that was initially created since they are all 'on the same level' hierarchically as one another.

In the example you gave, you've actually got three threads. T1 (which is P1), T2 and T3 (the two threads created).

The state of P1 (T1) is indeterminate, because unless it is specifically waiting for any of the other threads in some manner, it can be runnable, sleeping, running or any other state.

To understand the relationship that threads and processes have, see the diagram below.

                         pthread_create()
   ┌──Pid┼P1──┐                                   ┌──Pid┼P1──┐
   │          │     clone(...CLONE_THREAD...)     │          │
   │ Thread T1│     clone(...CLONE_THREAD...)     │ Thread T1│
   │          │     ...                           │ Thread T2│
   │          │     clone(...CLONE_THREAD...)     │ ...      │
   │          │  ─────────────────────────────►   │ Thread TN│
   └──────────┘                                   └──────────┘

─────────────────────────────────────────────────────────────────

                       fork()
   ┌──Pid┼P1──┐                      ┌──Pid┼P1──┐
   │          │     clone()          │ Thread T1│    ...
   │ Thread T1│     clone()          └──────────┘
   │          │     ...
   │          │     clone()          ┌──Pid┼P2──┐ ┌──Pid┼PN──┐
   │          │  ───────────►        │ Thread T1│ │ Thread T1│
   └──────────┘                      └──────────┘ └──────────┘

A PID really is just a container that accounts and describes threads that all share the same resources inside it.**

Most PIDs you run have one thread (technically a runnable context) inside of them. When you create new threads you're merely declaring two runnable contexts inside the same PID container.

If you perform a fork() you get an entirely new container and a new thread inside of it.


*There is a "main" thread (the initial from the process) that is permitted only to make certain calls that redescribe the behaviour of the PID as a whole. This is the closest to a heirarchy there is.

**Just for the sake of descriptive clarity I'm overlooking many other properties of threads and what they share, along with processes hierarchies and what they share to explain the basic nature of threads and processes.

1
  • "The state of P1 (T1) is indeterminate, because unless it is specifically waiting for any of the other threads in some manner, it can be runnable, sleeping, running or any other state." So based on what you wrote, the initial thread T1 determines the state of the process P. State of T1 (in TCB) and state of P (in PCB) are basically interchangeable. The purpose of a process state is to know if the parent thread is blocked (can cause zombie processes), terminated (can cause orphan process), or running.
    – X XXX X
    Commented May 27, 2022 at 17:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .