【发布时间】:2021-01-04 03:29:06
【问题描述】:
我正在尝试使用WaitOnAddress()函数来实现读写同步。
According to MSDN、WaitOnAddress() 具有以下声明:
BOOL WaitOnAddress(
volatile VOID *Address,
PVOID CompareAddress,
SIZE_T AddressSize,
DWORD dwMilliseconds
);
以及如下参数定义:
比较地址
指向先前观察到的值在
Address的位置的指针。当Address的值与CompareAddress的值不同时,该函数返回。
根据定义,我应该存储并传递被监视地址的当前值,所以当监视值发生变化时,WaitOnAddress() 会返回。但是这个功能并没有像我预期的那样工作,所以我在 Visual Studio 中为WaitOnAddress() 编写了以下测试代码(还包括链接器库Synchronization.lib):
#include <stdio.h>
#include <stdlib.h> // atoi
#include <string.h>
// include these two files after including winsock2.h
#include <process.h>
#include <Windows.h>
#include <synchapi.h>
void* threads(void* num) {
int* number = (int*)num;
for (int i = 0; i < 10; i++) {
printf("number = %d\n", *number);
}
int catch = *number; // will be passed as CompareAddress
WaitOnAddress((int*)num, &catch, sizeof(int), INFINITE);
for (int i = 0; i < 10; i++) {
printf("number2 = %d, %d\n", catch, *(int*)num);
}
return NULL;
}
int main() {
int int_list[10];
for (int i = 0; i < 10; i++) {
int_list[i] = i;
_beginthread(threads, 0, (void*)&int_list[i]);
}
printf("hello\n");
Sleep(1000);
for (int i = 0; i < 10; i++) {
int_list[i] = 10 - i;
}
printf("changed\n");
Sleep(1000);
return 0;
}
在上面的代码中,WaitOnAddress() 永远不会返回,即使它监视的值发生了变化。但是,如果我改变了
int catch = *number;
到:
int catch = 10 - *number;
然后WaitOnAddress() 返回并打印输出的其余部分,就好像它仅在观察值与比较值匹配时才返回。
但是,我想使用所描述的行为,以便在监视变量发生更改时释放我的线程。
【问题讨论】:
-
在父级更改所有值之前,如何确定线程已达到
WaitOnAddress?你能显示输出日志吗? -
从您链接到的文档中:“直到同一进程中的另一个线程通过调用 WakeByAddressSingle 或 WakeByAddressAll 或超时,以先到者为准”
-
@kaylum 感谢您提醒我。在另一次修订后,我发现了一个错误的假设,我得出了错误的结论。
-
@RaymondChen 确实,谢谢,我很抱歉。每次阅读该页面时,我怎么会错过那句话?...下次我应该更仔细地阅读手册。顺便说一句,我可以问我应该怎么做我的问题,因为它在stackoverflow中没有意义?我担心删除会是对你们两个发布的消息的不尊重,但我没有找到关闭按钮。