Search code examples
cmultithreadingwhile-loopgtkwinsock

Odd behavior of Windows thread


I am combining GTK+, WinAPI and Winsock to create a graphical client-server interface, a waiting room. nUsers is a variable that determines the number of clients successfully connected.

Within a Windows thread, created by:

CreateThread(NULL, 0, action_to_users, NULL, 0, NULL);

I use the do-nothing while loop so that it freezes until a user connects.

while(!nUsers);

However, it never passes through the loop as if nUsers never becomes > 0.nUsers counts the number of clients connected properly, as I constantly monitor it and use it in a variety of different functions. To prove my point, something even stranger happens. If I make the loop

while(!nUsers) { printf("(%i)\n", nUsers); }

To spam the console with text printed out (doesn't matter what text as long as it is not an empty string) it works as intended.


What could be possibly going on here...


Solution

  • Regarding the original problem: compiler is free to cache the value of nUsers since the variable is not modified within this loop. Marking the variable volatile prevents this optimization as described here.

    Regarding what you're trying to achieve - it looks like a producer-consumer pattern, where the thread(s) handling the sockets are producers and your GUI thread is a consumer. You can slow down your consumer loop to only loop when new data is available using:

    • semaphores as showcased here - producer thread increments count on semaphore while consumer decrements it upon dequeing work item.
    • Events like here - producer thread signals an event while consumer thread waits for it to become signalled. You can queue the work in some queue to allow more than one item being processed.
    • Condition variables (XP+) - here a variable you're waiting for gets signalled upon meeting certain criteria.