Do Suspended or Blocked Threads Consume CPU Time?

The short answer is no. Suspended or blocked thread do not consume any CPU time.

Of course, I didn’t know that. This is just a journal on how I wasted a perfectly nice afternoon.

Earlier…

I searched the internet, and found a MSDN article on scheduling priorities.

The system assigns time slices in a round-robin fashion to all threads with the highest priority. If none of these threads are ready to run, the system assigns time slices in a round-robin fashion to all threads with the next highest priority. If a higher-priority thread becomes available to run, the system ceases to execute the lower-priority thread (without allowing it to finish using its time slice), and assigns a full time slice to the higher-priority thread.

To me, the above paragraph sounded like all threads, regardless of state, are assigned to some time slices based on priority. So I wrote some test code to gain some insight.

Below is a test program that runs four threads to calculate Pi (on my quad-core CPU), and 1000 real-time priority sleeper thread that runs Sleep(). If suspended threads use any CPU cycles, it will definitely slow down the Pi calculation.

#include <Windows.h>
#include <iostream>
#include <boost/thread.hpp>
#include <boost/cstdint.hpp>

using boost::bind;
using boost::thread;
using boost::mutex;
using boost::condition_variable;

void calculatePi()
{
	double retPi = 0;
	for (boost::uint64_t denom = 1; denom <= 30000000000; denom += 2)
	{
		if ((denom - 1) % 4)
			retPi -= (4.0 / denom);
		else
			retPi += (4.0 / denom);
	}
}

void sleepForever()
{
	Sleep(10000000);
}

int main()
{
	std::vector<thread> tv;
	std::vector<thread> stv;

	// 1000 real time priority thread that sleeps
	for(int i=0; i<1000; ++i)
	{
		thread s(bind(&sleepForever));
		SetPriorityClass(s.native_handle(), REALTIME_PRIORITY_CLASS);
		stv.push_back(std::move(s));
	}

	// four normal priority thread that calculates pi
	for(int i=0; i<4; ++i)
	{
		thread w(bind(&calculatePi));
		tv.push_back(std::move(w));
	}

	for(size_t i=0; i<tv.size(); ++i)
	{
		tv[i].join();
	}
	return 0;
}

The Result

There is absolutely no difference in performance when the test program runs 10, 100, or 1000 sleeper threads.

Using the concurrency profiler in VC10, it shows that threads in suspended state are never context-switched or woken up during its lifetime.

Last four threads calculates Pi, the the other threads are sleeping. Sleeping thread did not execute, and therefore did not consume any CPU cycles.

Then I ran into another MSDN documentation on context switches.

Until threads that are suspended or blocked become ready to run, the scheduler does not allocate any processor time to them, regardless of their priority.

Yup. I have verified that the documentation is accurate. 😥

3 thoughts on “Do Suspended or Blocked Threads Consume CPU Time?

Leave a Reply

Your email address will not be published. Required fields are marked *