From the course: Parallel and Concurrent Programming with C++ Part 1

Thread versus process: C++ demo - C++ Tutorial

From the course: Parallel and Concurrent Programming with C++ Part 1

Start my 1-month free trial

Thread versus process: C++ demo

- [Instructor] Now, before we demonstrate a process with multiple threads in action, let's first take a look at the number of processors that are available on this computer, which we'll be using for demonstrations throughout this course. To do that, I'll press Ctrl + Shift + Escape, which opens the Task Manager, and then go to the Performance tab. Down at the bottom, we can see that this computer has two cores and four logical processors. Those numbers mean that this computer has two separate and complete physical processing cores and each of those cores supports something called hyper-threading, which enables them to each run two independent threads at the same time. So, the computer treats those two physical cores as four logical processors. Now, the hyper-threading in those two cores does not mean I'll get double the performance out of each of them. Hyper-threading takes advantage of unused parts of the processor, so if one thread is paused or not using a specific resource, then the other thread may be able to use it. Under certain workloads, that can create performance improvements, but it's highly application-dependent. The moving blue graph shows the total percentage of CPU utilization for all of those processors. I don't have much running right now, so the usage stays low, down near just a few percent. If I want to see the CPU usage for each of those processors individually, I can get more information by clicking the Open Resource Monitor link... and then selecting the CPU tab. The charts on the right show the total CPU usage on top and, if I scroll down, I can see how much each of the individual processors on this computer are being utilized. The table on the left lists all of the current processes running on this computer with information including each process's unique process ID number, its PID, its current status, the number of threads, and its average CPU usage. Now, to show you a few threads running in a process, we've created this short example program which you can find in the Exercise Files, Chapter Two 02_02 Begin directory. This program defines a simple function on line nine called cpu_waster which can be used to create a new thread that spins in a while loop forever. It prints the process ID on line ten using the getpid function, which is declared in the unistd header and then, on line 11, it uses the getid function to print the current thread ID. After that, the cpu_waster enters into an infinite while loop. It's not doing anything useful, but the thread will stay alive forever and continuously use CPU cycles. Down in this program's main function, lines 16 and 17 print messages with the process ID and main thread's ID value. Then, after that, the program instantiates two new threads. To create threads throughout this course, we'll be using the C++ Standard Library's thread class, which is defined in the thread header file. How threads are actually compiled and implemented under the hood can vary between operating systems, but by writing our code using the standard library classes, it should be portable to different development environments. The two new thread objects created on lines 18 and 19, named thread1 and thread2, are assigned the cpu_waster as their top-level function to execute. After those two threads start, the main thread enters into its own infinite while loop on line 21 to keep the process alive. Now, I'll switch over to a command prompt opened to a folder with the example code and I'll use the make command to build the program. It warns me that the data type used to represent a thread ID may not be compatible with the printf function because it's not actually an integer data type, but for the sake of this demonstration, that's okay. The printf function will do its best to display the thread ID as a numeric value, which will be enough to at least see that the three threads in this program are different. Now I'll run the executable: thread_process_demo.exe. I can see that the operating system assigned this program the process ID number 232 and the main thread has an ID value represented by this number: 98368. The two CPU Waster threads that were created have the same process ID as the main thread, but they each have their own unique thread IDs. Switching over to the Task Manager, I can see that the overall CPU usage has jumped to over 50%. That's because the two CPU Waster threads I created are running continuously and using CPU resources on half of the four logical processors on this computer. Looking at the Resource Monitor's CPU tab, I can see how that workload is being distributed across all of those processors. If I scroll down in the Processes window... I see a process called thread_process_demo.exe. Now, you may have noticed that it has a different process ID number than our program displayed earlier, and that's because we're using Cygwin to emulate a POSIX-compatible environment on our Windows computer. The process ID shown here in the Windows Resource Monitor is the ID that Windows assigned the process, whereas the value the program printed out was the process ID it got from the Cygwin emulation environment. This program will continue running forever if I don't stop it, so I'll manually terminate it by closing the Command Prompt window that was running the program. If I look at the CPU usage now, I can see that, when I close the program, those CPU-wasting threads were terminated too and the CPU usage dropped back down to just a few percent.

Contents