What is the difference between process and thread?

The major difference between process and thread is that threads (of the same process) run in shared memory space, while processes run in separate memory spaces.

Let’s learn more about the differences between processes and threads thoroughly.

Process

Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, open handles to system objects, a security context, a unique process identifier, environment variables, a priority class, minimum and maximum working set sizes, and at least one thread of execution. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads.

Thread

A thread is an entity within a process that can be scheduled for execution. All threads of a process share its virtual address space and system resources. In addition, each thread maintains exception handlers, a scheduling priority, thread local storage, a unique thread identifier, and a set of structures the system will use to save the thread context until it is scheduled. The thread context includes the thread’s set of machine registers, the kernel stack, a thread environment block, and a user stack in the address space of the thread’s process. Threads can also have their own security context, which can be used for impersonating clients.


This information was found on Microsoft Docs here: About Processes and Threads

Microsoft Windows supports preemptive multitasking, which creates the effect of simultaneous execution of multiple threads from multiple processes. On a multiprocessor computer, the system can simultaneously execute as many threads as there are processors on the computer.

What is the difference between process and thread?

Both processes and threads are independent sequences of execution. The typical difference is that threads (of the same process) run in shared memory space, while processes run in separate memory spaces.

I’m not sure what “hardware” vs “software” threads you might be referring to. Threads are an operating environment feature, rather than a CPU feature (though the CPU typically has operations that make threads efficient).

Erlang uses the term “process” because it does not expose a shared-memory multiprogramming model. Calling them “threads” would imply that they have shared memory.

Process vs Thread:

Process:

  • An executing instance of a program is called a process.
  • Some operating systems use the term ‘task‘ to refer to a program that is being executed.
  • A process is always stored in the main memory also termed the primary memory or random access memory.
  • Therefore, a process is termed an active entity. It disappears if the machine is rebooted.
  • Several processes may be associated with the same program.
  • On a multiprocessor system, multiple processes can be executed in parallel.
  • On a uni-processor system, though true parallelism is not achieved, a process scheduling algorithm is applied and the processor is scheduled to execute each process one at a time yielding an illusion of concurrency.
  • Example: Executing multiple instances of the ‘Calculator’ program. Each of the instances is termed as a process.

Thread:

  • A thread is a subset of the process.
  • It is termed as a ‘lightweight process’, since it is similar to a real process but executes within the context of a process and shares the same resources allotted to the process by the kernel.
  • Usually, a process has only one thread of control – one set of machine instructions executing at a time.
  • A process may also be made up of multiple threads of execution that execute instructions concurrently.
  • Multiple threads of control can exploit the true parallelism possible on multiprocessor systems.
  • On a uni-processor system, a thread scheduling algorithm is applied and the processor is scheduled to run each thread one at a time.
  • All the threads running within a process share the same address space, file descriptors, stack and other process-related attributes.
  • Since the threads of a process share the same memory, synchronizing the access to the shared data within the process gains unprecedented importance.

Answer #3:

First, let’s look at the theoretical aspect. You need to understand what a process is conceptually to understand the difference between a process and a thread and what’s shared between them.

We have the following in section 2.2.2 The Classical Thread Model of Modern Operating Systems 3e by Tanenbaum:

The process model is based on two independent concepts: resource grouping and execution. Sometimes it is use­ful to separate them; this is where threads come in….

He continues:

One way of looking at a process is that it is a way to group related resources together. A process has an address space containing program text and data, as well as other resources. These resource may include open files, child processes, pending alarms, signal handlers, accounting information, and more. By putting them together in the form of a process, they can be managed more easily. The other concept a process has is a thread of execution, usually shortened to just thread. The thread has a program counter that keeps track of which instruc­tion to execute next. It has registers, which hold its current working variables. It has a stack, which contains the execution history, with one frame for each proce­dure called but not yet returned from. Although a thread must execute in some process, the thread and its process are different concepts and can be treated sepa­rately. Processes are used to group resources together; threads are the entities scheduled for execution on the CPU.

Further down he provides the following table:

Per process items             | Per thread items
------------------------------|-----------------
Address space                 | Program counter
Global variables              | Registers
Open files                    | Stack
Child processes               | State
Pending alarms                |
Signals and signal handlers   |
Accounting information        |

Let’s deal with the hardware multithreading issue. Classically, a CPU would support a single thread of execution, maintaining the thread’s state via a single program counter (PC), and set of registers. But what happens when there’s a cache miss? It takes a long time to fetch data from main memory, and while that’s happening the CPU is just sitting there idle. So someone had the idea to basically have two sets of thread state (PC + registers) so that another thread (maybe in the same process, maybe in a different process) can get work done while the other thread is waiting on main memory. There are multiple names and implementations of this concept, such as Hyper-threading and simultaneous multithreading (SMT for short).

Now let’s look at the software side. There are basically three ways that threads can be implemented on the software side.

  1. User space threads
  2. Kernel threads
  3. A combination of the two

All you need to implement threads is the ability to save the CPU state and maintain multiple stacks, which can in many cases be done in user space. The advantage of user space threads is super fast thread switching since you don’t have to trap into the kernel and the ability to schedule your threads the way you like. The biggest drawback is the inability to do blocking I/O (which would block the entire process and all its user threads), which is one of the big reasons we use threads in the first place. Blocking I/O using threads greatly simplifies program design in many cases.

Kernel threads have the advantage of being able to use blocking I/O, in addition to leaving all the scheduling issues to the OS. But each thread switch requires trapping into the kernel which is potentially relatively slow. However, if you’re switching threads because of blocked I/O this isn’t really an issue since the I/O operation probably trapped you into the kernel already anyway.

Another approach is to combine the two, with multiple kernel threads each having multiple user threads.

So getting back to your question of terminology, you can see that a process and a thread of execution are two different concepts and your choice of which term to use depends on what you’re talking about. Regarding the term “light weight process”, I don’t personally see the point in it since it doesn’t really convey what’s going on as well as the term “thread of execution”.

Difference between process and thread

An application consists of one or more processes. A process, in the simplest terms, is an executing program. One or more threads run in the context of the process.

A thread is a basic unit to which the operating system allocates processor time. A thread can execute any part of the process code, including parts currently being executed by another thread. Fiber is a unit of execution that must be manually scheduled by the application. Fibers run in the context of the threads that schedule them.

To explain more with respect to concurrent programming

  1. A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space.
  2. Threads exist within a process — every process has at least one. Threads share the process’s resources, including memory and open files. This makes for efficient, but potentially problematic, communication.

An example keeping the average person in mind:

On your computer, open Microsoft Word and a web browser. We call these two processes.

In Microsoft Word, you type something and it gets automatically saved. Now, you have observed editing and saving happens in parallel – editing on one thread and saving on the other thread.

Also read: From UNIX to Linux – History of Linux

Process vs thread- example:

Real-world example for Process and Thread This will give you the basic idea about thread and process:

Difference between threads and processes with respect to Java:

Trying to answer this question relating to Java world.

A process is an execution of a program but a thread is a single execution sequence within the process. A process can contain multiple threads. A thread is sometimes called a lightweight process.

For example:

Example 1: A JVM runs in a single process and threads in a JVM share the heap belonging to that process. That is why several threads may access the same object. Threads share the heap and have their own stack space. This is how one thread’s invocation of a method and its local variables are kept thread safe from other threads. But the heap is not thread-safe and must be synchronized for thread safety.

Example 2: A program might not be able to draw pictures by reading keystrokes. The program must give its full attention to the keyboard input and lacking the ability to handle more than one event at a time will lead to trouble. The ideal solution to this problem is the seamless execution of two or more sections of a program at the same time. Threads allows us to do this. Here Drawing picture is a process and reading keystroke is sub process (thread).

Answer #7- Threads and processes by Linus Torvalds:

Linus Torvalds (torvalds@cs.helsinki.fi)

Tue, 6 Aug 1996 12:47:31 +0300 (EET DST)

Messages sorted by: [ date ][ thread ][ subject ][ author ]

Next message: Bernd P. Ziller: “Re: Oops in get_hash_table”

Previous message: Linus Torvalds: “Re: I/O request ordering”

On Mon, 5 Aug 1996, Peter P. Eiserloh wrote:

We need to keep a clear the concept of threads. Too many people seem to confuse a thread with a process. The following discussion does not reflect the current state of linux, but rather is an attempt to stay at a high level discussion.

NO!

There is NO reason to think that “threads” and “processes” are separate entities. That’s how it’s traditionally done, but I personally think it’s a major mistake to think that way. The only reason to think that way is historical baggage.

Both threads and processes are really just one thing: a “context of execution”. Trying to artificially distinguish different cases is just self-limiting.

A “context of execution”, hereby called COE, is just the conglomerate of all the state of that COE. That state includes things like CPU state (registers etc), MMU state (page mappings), permission state (uid, gid) and various “communication states” (open files, signal handlers etc). Traditionally, the difference between a “thread” and a “process” has been mainly that a threads has CPU state (+ possibly some other minimal state), while all the other context comes from the process. However, that’s just one way of dividing up the total state of the COE, and there is nothing that says that it’s the right way to do it. Limiting yourself to that kind of image is just plain stupid.

The way Linux thinks about this (and the way I want things to work) is that there is no such thing as a “process” or a “thread”. There is only the totality of the COE (called “task” by Linux). Different COE’s can share parts of their context with each other, and one subset of that sharing is the traditional “thread”/”process” setup, but that should really be seen as ONLY a subset (it’s an important subset, but that importance comes not from design, but from standards: we obviusly want to run standards-conforming threads programs on top of Linux too).

In short: do NOT design around the thread/process way of thinking. The kernel should be designed around the COE way of thinking, and then the pthreads library can export the limited pthreads interface to users who want to use that way of looking at COE’s.

Just as an example of what becomes possible when you think COE as opposed to thread/process:

  • You can do a external “cd” program, something that is traditionally impossible in UNIX and/or process/thread (silly example, but the idea is that you can have these kinds of “modules” that aren’t limited to the traditional UNIX/threads setup). Do a:

clone(CLONE_VM|CLONE_FS);

child: execve(“external-cd”);

/* the “execve()” will disassociate the VM, so the only reason we used CLONE_VM was to make the act of cloning faster */

  • You can do “vfork()” naturally (it meeds minimal kernel support, but that support fits the CUA way of thinking perfectly):

clone(CLONE_VM);

child: continue to run, eventually execve()

mother: wait for execve

  • you can do external “IO deamons”:

clone(CLONE_FILES);

child: open file descriptors etc

mother: use the fd’s the child opened and vv.

All of the above work because you aren’t tied to the thread/process way of thinking. Think of a web server for example, where the CGI scripts are done as “threads of execution”. You can’t do that with traditional threads, because traditional threads always have to share the whole address space, so you’d have to link in everything you ever wanted to do in the web server itself (a “thread” can’t run another executable).

Thinking of this as a “context of execution” problem instead, your tasks can now chose to execute external programs (= separate the address space from the parent) etc if they want to, or they can for example share everything with the parent except for the file descriptors (so that the sub-“threads” can open lots of files without the parent needing to worry about them: they close automatically when the sub-“thread” exits, and it doesn’t use up fd’s in the parent).

Think of a threaded “inetd”, for example. You want low overhead fork+exec, so with the Linux way you can instead of using a “fork()” you write a multi-threaded inetd where each thread is created with just CLONE_VM (share address space, but don’t share file descriptors etc). Then the child can execve if it was a external service (rlogind, for example), or maybe it was one of the internal inetd services (echo, timeofday) in which case it just does it’s thing and exits.

You can’t do that with “thread”/”process”.

Linus

Hope you learned something from this post.

Follow Programming Articles for more!

About ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ

Linux and Python enthusiast, in love with open source since 2014, Writer at programming-articles.com, India.

View all posts by ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ →