mingw 4.6.1 原子失败?
所以我发现 gcc 已经有了 std::atomic 的工作实现,所以我想尝试一下,这是我使用 boost 线程 1.48 和 std::atomic 的示例:
#include <iostream>
#define BOOST_THREAD_USE_LIB
#include <boost/thread.hpp>
#include <atomic>
#include <string>
using namespace std;
using namespace boost;
class Server
{
public:
atomic<bool> running;
thread main_server_thread;
void func1()
{
while(running)
{
//do stuff
}
}
void func2()
{
while(running)
{
//do stuff
}
}
void func3()
{
while(running)
{
//do stuff
}
}
void func4()
{
string input;
while(running)
{
//do stuff
input.clear();
getline(cin,input);
if(input=="quit")running=false;
}
}
void main_function()
{
thread thrd1(bind(&Server::func1,this));
thread thrd2(bind(&Server::func2,this));
thread thrd3(bind(&Server::func3,this));
thread thrd4(bind(&Server::func4,this));
while(running)
{
//do stuff
}
thrd1.join();
thrd2.join();
thrd3.join();
thrd4.join();
}
Server()
{
running=true;
main_server_thread = thread(&Server::main_function,this);
}
};
int main()
{
Server* serv = new Server();
serv->main_server_thread.join();
return 0;
}
现在,虽然 running
保持 true
一切都很好,但是当用户输入 quit
且 running
设置为 false
一些线程结束,一些线程结束 不。无论有没有优化,都会发生这种情况。这是否按预期工作?根据我对原子的理解,读取不应与写入发生冲突,因此线程应该在某个时刻看到 running=false
。
编辑: func1 的反汇编:
void func1()
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 18 sub $0x18,%esp
{
while(running)
6: 90 nop
7: 8b 45 08 mov 0x8(%ebp),%eax
a: 89 04 24 mov %eax,(%esp)
d: e8 00 00 00 00 call 12 <__ZN6Server5func1Ev+0x12>
12: 84 c0 test %al,%al
14: 75 f1 jne 7 <__ZN6Server5func1Ev+0x7>
{
//do stuff
}
}
16: c9 leave
17: c3 ret
So I discovered that gcc already had a working implementation of std::atomic
so I wanted to try it out, here is my example using boost thread 1.48 and std::atomic
:
#include <iostream>
#define BOOST_THREAD_USE_LIB
#include <boost/thread.hpp>
#include <atomic>
#include <string>
using namespace std;
using namespace boost;
class Server
{
public:
atomic<bool> running;
thread main_server_thread;
void func1()
{
while(running)
{
//do stuff
}
}
void func2()
{
while(running)
{
//do stuff
}
}
void func3()
{
while(running)
{
//do stuff
}
}
void func4()
{
string input;
while(running)
{
//do stuff
input.clear();
getline(cin,input);
if(input=="quit")running=false;
}
}
void main_function()
{
thread thrd1(bind(&Server::func1,this));
thread thrd2(bind(&Server::func2,this));
thread thrd3(bind(&Server::func3,this));
thread thrd4(bind(&Server::func4,this));
while(running)
{
//do stuff
}
thrd1.join();
thrd2.join();
thrd3.join();
thrd4.join();
}
Server()
{
running=true;
main_server_thread = thread(&Server::main_function,this);
}
};
int main()
{
Server* serv = new Server();
serv->main_server_thread.join();
return 0;
}
Now while running
remains true
all is fine but when the user inputs quit
and running
is set to false
some threads end and some don't. This happens with and without optimizations. Is this working as intended? In my understanding of atomics the reads shouldn't conflict with the one write so the threads should see the running=false
at some point.
EDIT:
Disassembly of func1:
void func1()
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 18 sub $0x18,%esp
{
while(running)
6: 90 nop
7: 8b 45 08 mov 0x8(%ebp),%eax
a: 89 04 24 mov %eax,(%esp)
d: e8 00 00 00 00 call 12 <__ZN6Server5func1Ev+0x12>
12: 84 c0 test %al,%al
14: 75 f1 jne 7 <__ZN6Server5func1Ev+0x7>
{
//do stuff
}
}
16: c9 leave
17: c3 ret
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如反汇编所示,该程序在使用 mingw 编译时,不会将
running
视为原子操作:它加载的是常规mov 0x8(%ebp),%eax
没有同步。与 linux/x86_64 上 gcc-4.6.2 的输出进行比较:
要么 mingw 尚不支持,要么其配置中缺少某些内容。
As the disassembly shows, this program, when compiled with mingw, does not treat
running
as an atomic: it is loaded with a regularmov 0x8(%ebp),%eax
without synchronization.Compare to the output of gcc-4.6.2 on linux/x86_64:
Either mingw doesn't support that yet, or something is missing in its configuration.