Thread/Process in Linux

This article is about the introduction of parallel programming in Linux .

Threads and processes are both powerful tools for concurrent and parallel execution in a Linux environment, but they have different characteristics and are suited for different types of tasks. Understanding the differences between the two, and being familiar with the thread and process management functions provided by the Linux operating system, is crucial for making the most effective use of these tools.

Threads and processes are both fundamental concepts in computer science, and they are often used interchangeably. However, there are some key differences between the two that are important to understand in order to effectively use them in your programming, particularly in a Linux environment.

In Linux, threads are implemented as a lightweight alternative to processes, and they are known as "lightweight processes" or "LWP". They share the same memory space as the parent process and scheduled by the kernel, which means they can communicate with each other more easily and efficiently. This makes them well-suited for tasks that require concurrent execution, such as GUI programming, web servers, and database systems.

Process is a running instance of a program. Each process has its own virtual memory space, program code, data, and resources, such as file descriptors and signals. Processes are isolated from each other and communicate using inter-process communication mechanisms such as pipes, sockets, and shared memory.

Threads, on the other hand, are light-weight units of execution within a process. Each thread shares the same virtual memory space and resources as other threads within the same process, but has its own program counter, stack, and register state. Threads are scheduled by the operating system's scheduler, which decides when to give each thread CPU time based on various factors such as priority, time slice, and blocking state.

Processes, on the other hand, are independent, self-contained execution environments, with their own memory space. Each process has its own address space, file descriptors, and other resources, which means that communication between processes is more complex and resource-intensive. Processes are typically used for tasks that do not require concurrent execution, such as batch processing and scientific simulations.

In Linux, the scheduler is responsible for managing the execution of threads and processes. It uses a priority-based algorithm to determine which thread or process should be executed next, and assigns a priority value to each thread or process. The scheduler uses this value to determine the order in which threads and processes are executed, with higher priority threads and processes being executed before lower priority ones.

In terms of usage, threads are often used in GUI programming, web servers, and database systems, while processes are typically used for batch processing and scientific simulations. However, the choice between threads and processes depends on the specific requirements of your application, and there is no one-size-fits-all solution.

When deciding whether to use threads or processes, it is important to consider factors such as the amount of inter-task communication required, the level of security or data integrity needed, and the performance requirements of your application. Additionally, it is important to be familiar with the thread and process management functions provided by the Linux operating system, such as pthreads library, and to use them correctly in order to ensure that your application runs smoothly and efficiently.

A process and a thread are both mechanisms for achieving concurrency in an operating system. However, they have some key differences:

  1. Memory Space: Processes have their own memory space, called virtual memory, which is separate from the memory space of other processes. Threads share the memory space of the process that created them.
  2. Scheduling: Processes are typically scheduled by the operating system to run on a single CPU or core, while threads are scheduled by the operating system to run on multiple CPUs or cores. Both processes and threads are scheduled by the kernel for execution, but the scheduling algorithm may treat them differently. For example, the kernel may use different scheduling policies for processes and threads.
  3. Resources: Processes have their own set of resources, such as file descriptors and open sockets, while threads share the resources of the parent process.
  4. Inter-communication: Processes have their own address space and can't directly communicate with other processes except via inter-process communication (IPC) mechanisms such as pipes, sockets, and message queues. Threads share the same address space and can communicate with other threads of the same process directly i.e global variables can be shared via resouce protections and sync mechanisms .
  5. Isolation: Processes are isolated from each other, if one process crashes it will not affect other processes. Threads, on the other hand, run in the same memory space and if one thread crashes, it could potentially bring down the entire process.

Processes are independent entities that are scheduled by the operating system, while threads are lightweight execution units that run within the context of a process and share the same memory space.

Deciding whether to use threads or processes for parallel processing is always a challenging but depends on the specific requirements of your application. Here are a few factors to consider when making this decision:

  1. Memory space: If your application requires separate memory spaces for different tasks, then processes are the better choice.
  2. Shared data: If the tasks need to share data, then threads are the better choice, since they share the same memory space.
  3. Synchronization: Threads are generally easier to synchronize than processes, since they share the same memory space. If your application requires a lot of synchronization between tasks, then threads may be the better choice.
  4. Isolation: If you want to isolate tasks, for example if one of them crash it does not affect the other, then you should use processes.
  5. Communication: If tasks need to communicate frequently, threads may be more efficient, since they share the same memory space and can communicate directly. Processes, on the other hand, typically use inter-process communication (IPC) mechanisms such as pipes, sockets, and message queues to communicate.
  6. Portability: If your application needs to be portable across different operating systems, you may prefer to use threads, since they are typically implemented using a standard library such as POSIX threads, which is available on most operating systems.

It's important to note that choosing the right parallel processing method can significantly improve the performance of your application. It's also possible to use both threads and processes in a single application, and use them together in a way that best suits the needs of the application.


At the kernel level, both processes and threads are considered as tasks and are scheduled by the operating system for execution. They both have their own unique process ID (PID) and consume system resources such as memory and CPU time.


At the kernel level, the main difference between processes and threads is how they use the system's resources, how they share those resources and how they are scheduled.

It's also important to note that the implementation of threads and processes can vary between different operating systems. Some operating systems, such as Linux, treat threads as a separate entity from processes while others like Windows, threads are implemented as a special type of process.

In some operating systems, such as Linux, the system call clone() is used to create both processes and threads. The clone() system call creates a new task that shares some or all of its resources with the calling task. By specifying different flags, it is possible to create either a new process or a new thread.

In other operating systems, such as Windows, the system call CreateProcess() is used to create a new process, while the system call CreateThread() is used to create a new thread.

In Linux, the fork() system call is used to create a new process by duplicating the calling process and the pthread_create() is used to create a new thread.

The specific system call used to create processes and threads can vary between operating systems, but it is possible that the same system call can be used to create both processes and threads depending on the specific flags and parameters passed to the system call.

What is POSIX? POSIX stands for Portable Operating System Interface. POSIX defines the set of standard operating system interfaces based on the *nix OS. The latest spec is IEEE Std 1003.1-2017 2017. Please check the details about posix from the wiki link below

The POSIX are written in C/C++ based on standards. As you know threads are helpful in creating the concurrent process flow.

In C, the POSIX thread library, also known as pthreads, provides a set of functions for creating and manipulating threads. To create a new thread, you can use the pthread_create() function. This function takes three arguments:

int id2 = pthread_create(pthread_t* thread_id,pthread_attr_t* attr, void (*function)(void*),void* param);

  1. A pointer to a pthread_t variable, which will be used to store the thread ID of the newly created thread.
  2. A pointer to a pthread_attr_t variable, which can be used to set attributes for the new thread (such as the thread's scheduling policy or stack size). This argument is optional and can be set to NULL if the default attributes should be used.
  3. A pointer to the function that the new thread should execute. This function should have a void * argument and return void *.
  4. Last parameter is void* which is parameter to be sent to thread function from parent thread or process.

For example, the following code creates a new thread that executes the myThreadFunction() function:

#include<pthread.h>
void *myThreadFunction(void *arg);

int main() {
    pthread_t myThread;
    pthread_create(&myThread, NULL, myThreadFunction, NULL);
    // ...
    pthread_exit(NULL);
}

void *myThreadFunction(void *arg) {
    // thread code here
    return NULL;
}        

It's important to note that after creating a thread with pthread_create, it will run concurrently with the calling thread.

pthread_exit() function can be used in a way that allows the child thread to continue execution even after the parent thread has completed or terminated.

When the parent thread calls pthread_exit(), it terminates the execution of the parent thread and any other threads that are still running in the process. However, the child thread, which was created using pthread_create(), can continue to run independently of the parent thread.

This is because the child thread has its own stack and register values, and it is scheduled and managed by the operating system's kernel separately from the parent thread.

This is particularly useful when you want to run a background task that should continue running even after the parent thread has completed its execution. For example, a daemon process or a network service that should keep running even after the parent process exits.

It's also important to note that if the main thread exits without joining or detaching the child thread, the behavior is undefined, and it could cause resource leaks or other unexpected behavior.

To wait for thread to complete its execution, we need to use pthread_join() function which takes two arguments, thread id and return value pointer.


void *thread_result
pthread_join(myThread, &thread_result);;        


We need to include the pthread.h to use the pthread functions.

We need to link the pthread lib i.e lpthread which is shared lib(libpthread.so) to run the threaded programs.

g++ pthreadProigram.cpp -lpthread -o pthreadOut

My reference programs don't check for the return values of thread functions .

But in real code we need to check the return values of each thread function and check for any possible errors and take actions.


How to create the process in Linux ?

Please see the detailed article about process in below :

Brief on Linux process | LinkedIn

How to display threads in a process :

Using below command :

top -H -p PID

example : top -H -p 8970        

PID refers to process id of a process which conatins the threads to be displayed.

Detailed article :

How to Display Threads Associated with a Process in Linux


I hope you will find this article useful in some way !

If you have any questions or suggestions, please leave a comment.


Nice read:

Linkedin post : https://www.dhirubhai.net/posts/kamlesh-gurudasani_linux-assignments-userspace-activity-7303633215750094848-hsmc?utm_source=share&utm_medium=member_desktop&rcm=ACoAAADRiMoBvVTr28nJjXcpPGWfzSlmWKXXP5A

Prasanna Nandaragi

Embedded | Medical Devices | Automotive | Instrumentation | Consumer Electronics

5 个月

Nice write up !! Please review #4 on IPCs.

Anantha Narayanan

Project leader at Lennox India Tech. Private Limited

2 年

Very useful article Amit.. But one query, if a thread dies, how it could affect the process? It can block a resource & can lead to starvation. Isn't it?

要查看或添加评论,请登录

Amit Nadiger的更多文章

  • Rust modules

    Rust modules

    Referance : Modules - Rust By Example Rust uses a module system to organize and manage code across multiple files and…

  • List of C++ 17 additions

    List of C++ 17 additions

    1. std::variant and std::optional std::variant: A type-safe union that can hold one of several types, useful for…

  • List of C++ 14 additions

    List of C++ 14 additions

    1. Generic lambdas Lambdas can use auto parameters to accept any type.

    6 条评论
  • Passing imp DS(vec,map,set) to function

    Passing imp DS(vec,map,set) to function

    In Rust, we can pass imp data structures such as , , and to functions in different ways, depending on whether you want…

  • Atomics in C++

    Atomics in C++

    The C++11 standard introduced the library, providing a way to perform operations on shared data without explicit…

    1 条评论
  • List of C++ 11 additions

    List of C++ 11 additions

    1. Smart Pointers Types: std::unique_ptr, std::shared_ptr, and std::weak_ptr.

    2 条评论
  • std::lock, std::trylock in C++

    std::lock, std::trylock in C++

    std::lock - cppreference.com Concurrency and synchronization are essential aspects of modern software development.

    3 条评论
  • std::unique_lock,lock_guard, & scoped_lock

    std::unique_lock,lock_guard, & scoped_lock

    C++11 introduced several locking mechanisms to simplify thread synchronization and prevent race conditions. Among them,…

  • Understanding of virtual & final in C++ 11

    Understanding of virtual & final in C++ 11

    C++ provides powerful object-oriented programming features such as polymorphism through virtual functions and control…

  • Importance of Linux kernal in AOSP

    Importance of Linux kernal in AOSP

    The Linux kernel serves as the foundational layer of the Android Open Source Project (AOSP), acting as the bridge…

    1 条评论

社区洞察

其他会员也浏览了