hyperthreading locks up sleeping threads

OlafMeding at gmail.com OlafMeding at gmail.com
Mon May 8 10:13:44 EDT 2006


Below are 2 files.  The first is a Python program that isolates the
problem within less than 1 hour (often just a few minutes).  The second
is a C++ program that shows that the Win32 Sleep() function works as
expected (ran from Friday afternoon until Monday morning).

Note, the Python programs hangs (stops responding) with hyper-threading
turned on (a BIOS setting), but works as expected with hyper-threading
turned off.

This problem happens on Windows only (not on Linux for days).

Variations of the Python program also lock up:

Tried importing win32api instead of time and using the
win32api.GetTickCount() and win32api.Sleep() methods.

Tried using lock = threading.Event() and lock.wait() instead of
time.sleep().

Tried import Queue using q = Queue.Queue() and q.get(True, self.t).

Note, the Windows task manager shows 2 CPUs on the Performance tab with
hyper-threading is turned on.

Both Python 2.3.5 and 2.4.3 (downloaded from python.org) have this
problem.

The operating system is MS Windows XP Professional.

winmsd.exe shows:
2CPUs: x86 Family 15 Model 4 Stepping 1 GenuineIntel ~3000 MHz
Version: 5.1.2600 Service Pack 2 Build 2600

Could someone with a hyper-threading (or dual core or multi processor)
CPU please
confirm this bug?

Many Thanks

Olaf


Here is the expected output of both programs (the progam has locked up
if the numbers stop printing):
python testsleep.py
thread 1 started, sleep time 0.010
thread 2 started, sleep time 0.003
1 1 1 2 1 1 1 2 1 1 1 2 1 1 1 1 2 1 1 1


# testsleep.py
import threading
import time

class Task(threading.Thread):
	def __init__(self, n, t):
		threading.Thread.__init__(self)
		self.n = n  # thread id
		self.t = t  # sleep time
	def run(self):
		print 'thread %d started, sleep time %.3f' % (self.n, self.t)
		count = 0
		printCount = int(10 / self.t)
		while True:
			start = time.clock()
			time.sleep(self.t)
			stop = time.clock()
			if stop - start > 1.0:
				print 'thread', self.n, stop - start

			count += 1
			if count > printCount:
				count = 0
				print self.n,  # print sign of live

def test():
	thread1 = Task(1, 0.01)  # thread 1, sleep 10 ms
	thread2 = Task(2, 0.003) # thread 2, sleep  3 ms
	thread1.start()
	thread2.start()

test()

----------------------------------------------------------------------------------

// testsleep.cpp
// Compiled with Visual C++ version 6 as a Win32 console application.

#include <windows.h>
#include <stdio.h>
#include <time.h>

typedef struct {
    int id;
    int ms;
} param_s;


DWORD WINAPI threadFunction(LPVOID param)
{
    param_s* p = (param_s*)param;
    long elapsedTime;
    long time1, time2;
    long printCount = long(10000 / p->ms);  // loop iterations in 10
seconds
    long count = 0;

    printf("thread %d started, sleep time: %d ms" "\n", p->id, p->ms);

    while(true) {
        time1 = GetTickCount();
        Sleep(p->ms);
        time2 = GetTickCount();

        elapsedTime = time2 - time1;
        if(elapsedTime > 1000)
            printf("thread %d slept for %d ms" "\n", p->id,
elapsedTime);

        count++;
        if(count > printCount) {
            count = 0;
            printf("%d ", p->id);  // print sign of live
        }
    }

    return 0;
}


int main(int argc, char* argv[])
{
    long time1, time2;
    param_s p1, p2;

    p1.id = 1;
    p1.ms = 10;

    p2.id = 2;
    p2.ms = 3;

    time1 = GetTickCount();
    while(true) {
        time2 = GetTickCount();
        if (time1 != time2) {
            printf("clock resolution: %d ms" "\n", time2 - time1);
            break;
        }
    }

    CreateThread(NULL, 0, threadFunction, (void*)&p1, 0, NULL);
    CreateThread(NULL, 0, threadFunction, (void*)&p2, 0, NULL);

    getchar();  // wait until the user presses the enter key.

    return 0;
}




More information about the Python-list mailing list