Windows 线程的奇怪行为
Odd behavior of Windows thread
我正在结合 GTK+、WinAPI 和 Winsock 创建一个图形化的客户端-服务器界面,一个等候室。 nUsers
是一个变量,决定连接成功的客户端数量。
在 Windows 线程中,创建者:
CreateThread(NULL, 0, action_to_users, NULL, 0, NULL);
我使用了什么都不做的 while 循环,这样它就会冻结,直到用户连接。
while(!nUsers);
但是,它永远不会通过循环,就好像 nUsers
永远不会变为 > 0。nUsers
计算正确连接的客户端数量,因为我不断监视它并在各种情况下使用它不同的功能。
为了证明我的观点,发生了更奇怪的事情。
如果我循环
while(!nUsers) { printf("(%i)\n", nUsers); }
用打印出的文本向控制台发送垃圾邮件(不管是什么文本,只要它不是空字符串)它按预期工作。
这里可能发生了什么...
关于原始问题:编译器可以自由缓存 nUsers
的值,因为该变量未在此循环内修改。标记变量 volatile
可防止此优化,如 here.
所述
关于您要实现的目标 - 它看起来像是生产者-消费者模式,其中处理套接字的线程是生产者,而您的 GUI 线程是消费者。您可以减慢消费者循环,使其仅在有新数据可用时才循环:
- semaphores as showcased here - 生产者线程增加对信号量的计数,而消费者在工作项出队时减少它。
- Events like here - 生产者线程发出事件信号,而消费者线程等待它发出信号。您可以在某个队列中对工作进行排队,以允许处理多个项目。
- Condition variables (XP+) - 这里您等待的变量会在满足特定条件时发出信号。
我正在结合 GTK+、WinAPI 和 Winsock 创建一个图形化的客户端-服务器界面,一个等候室。 nUsers
是一个变量,决定连接成功的客户端数量。
在 Windows 线程中,创建者:
CreateThread(NULL, 0, action_to_users, NULL, 0, NULL);
我使用了什么都不做的 while 循环,这样它就会冻结,直到用户连接。
while(!nUsers);
但是,它永远不会通过循环,就好像 nUsers
永远不会变为 > 0。nUsers
计算正确连接的客户端数量,因为我不断监视它并在各种情况下使用它不同的功能。
为了证明我的观点,发生了更奇怪的事情。
如果我循环
while(!nUsers) { printf("(%i)\n", nUsers); }
用打印出的文本向控制台发送垃圾邮件(不管是什么文本,只要它不是空字符串)它按预期工作。
这里可能发生了什么...
关于原始问题:编译器可以自由缓存 nUsers
的值,因为该变量未在此循环内修改。标记变量 volatile
可防止此优化,如 here.
关于您要实现的目标 - 它看起来像是生产者-消费者模式,其中处理套接字的线程是生产者,而您的 GUI 线程是消费者。您可以减慢消费者循环,使其仅在有新数据可用时才循环:
- semaphores as showcased here - 生产者线程增加对信号量的计数,而消费者在工作项出队时减少它。
- Events like here - 生产者线程发出事件信号,而消费者线程等待它发出信号。您可以在某个队列中对工作进行排队,以允许处理多个项目。
- Condition variables (XP+) - 这里您等待的变量会在满足特定条件时发出信号。