首页 > 解决方案 > Threads in C in Windows

问题描述

The perfect way to run and terminate threads in Windows using C is mentioned in the answer below!

There are 2 problems I'm facing with the current implementation method :

  1. I can't forcibly stop the thread. For some reason it still continues. For example I have a for loop, it runs a function of which this thread example is a part. When this function is called 4-5 times, I see multiple animations on the screen suggesting that the previous threads didn't stop even when I called TerminateThread function at the end of my function.

  2. At times the thread doesn't run at all and no animation is displayed on the screen. Which is if my function code runs really fast or for some other reason, I feel like the thread is being killed before it initializes. Is there a way to wait until init of thread?

How do I fix these issues?

标签: cwinapi

解决方案


Correct way of terminating threads is to signal the thread and let it finish gracefully, i.e.:

(updated to use interlocked intrinsics instead of a volatile flag, as per @IInspectable's comment below)

HANDLE eventHnd;
HANDLE threadHnd;
LONG isStopRequested = 0;  // 1 = "stop requested"

static DWORD WINAPI thread_func(LPVOID lpParam)
{
    do
    {
        // wait until signalled from a different thread
        WaitForSingleObject(eventHnd, INFINITE);

        // end thread if stop requested
        if (InterlockedCompareExchange(&isStopRequested, 0, 0) == 1)
            return 0;

        // otherwise do some background work
        Sleep(500);

    } while (true);
}

The eventHnd variable is initialized using the CreateEvent function, and the stopRequested variable is just a boolean flag you can set from your main program:

// this creates an auto-reset event, initially set to 'false'
eventHnd = CreateEvent(NULL, false, false, NULL);
InterlockedExchange(&isStopRequested, 0);
threadHnd = CreateThread(NULL, 0, Processing_Thread, NULL, 0, NULL);

So, whenever you want to tell the thread do perform a task, you will simply set the event:

SetEvent(eventHnd);

And when you want to end the thread, you will set the flag to true, signal the event, and then wait for the thread to finish:

// request stop
InterlockedExchange(&isStopRequested, 1);

// signal the thread if it's waiting
SetEvent(eventHnd);

// wait until the thread terminates
WaitForSingleObject(threadHnd, 5000);

推荐阅读