简单的多线程互斥示例不正确
我希望以随机顺序获得从 0 到 4 的数字,但相反,我有一些不同步的混乱,
我做错了什么?
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
void addQuery(void *v );
HANDLE ghMutex;
int main()
{
HANDLE hs[5];
ghMutex = CreateMutex( NULL, FALSE, NULL);
for(int i=0; i<5; ++i)
{
hs[i] = (HANDLE)_beginthread(addQuery, 0, (void *)&i);
if (hs[i] == NULL)
{
printf("error\n"); return -1;
}
}
printf("WaitForMultipleObjects return: %d error: %d\n",
(DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());
return 0;
}
void addQuery(void *v )
{
int t = *((int*)v);
WaitForSingleObject(ghMutex, INFINITE);
cout << t << endl;
ReleaseMutex(ghMutex);
_endthread();
}
I expect to get numbers from 0 to 4 in random order, but instead, I have some unsynchronized mess
What i do wrong?
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
void addQuery(void *v );
HANDLE ghMutex;
int main()
{
HANDLE hs[5];
ghMutex = CreateMutex( NULL, FALSE, NULL);
for(int i=0; i<5; ++i)
{
hs[i] = (HANDLE)_beginthread(addQuery, 0, (void *)&i);
if (hs[i] == NULL)
{
printf("error\n"); return -1;
}
}
printf("WaitForMultipleObjects return: %d error: %d\n",
(DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());
return 0;
}
void addQuery(void *v )
{
int t = *((int*)v);
WaitForSingleObject(ghMutex, INFINITE);
cout << t << endl;
ReleaseMutex(ghMutex);
_endthread();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您必须在锁内读取和写入共享变量。您在锁之外读取它,从而使锁变得无关紧要。
但即使这样还不够,因为您的共享变量是一个循环变量,您在没有锁保护的情况下写入该变量。一个更好的例子是这样运行的:
如果可以的话,使用临界区而不是互斥锁,因为它们使用起来更简单并且更高效。但它们具有相同的语义,因为它们只保护锁定块内的代码。
注意:Jerry 指出了一些其他问题,但我集中讨论了高级标题和序列化问题。
You have to read and write the shared variable inside the lock. You are reading it outside of the lock and thus rendering the lock irrelevant.
But even that's not enough since your shared variable is a loop variable that you are writing to without protection of the lock. A much better example would run like this:
If you can, use a critical section rather than a mutex because they are simpler to use and more efficient. But they have the same semantics in that they only protect code inside the locking block.
Note: Jerry has pointer out some other problems, but I've concentrated on the high level trheading and serialization concerns.
您的
同步
存在一些问题,因为您希望以随机顺序获取 0 到 4 之间的数字。问题是变量
i
是在锁之外写入的,每次执行线程调用addQuery
方法时,它都会获取变量的修改版本>我。这就是为什么您可能会看到
5
作为所有输出的值。所以,这是我对这种情况的修复。您应该传递它的值,而不是在函数
addQuery
的参数中传递变量i
的地址。希望有帮助:Your
synchronization
has some issues as you want to get numbers from 0 to 4 in random order.The problem is that the variable
i
is write outside the lock and every time theaddQuery
method get called by the execution of a thread, it get the modified version of variablei
. That why you may see5
as the value at the output for all.So, here is my fix for this scenario. Instead of pass the address of variable
i
in parameters of the functionaddQuery
, you should pass it's value. Hope it helps: