Итак, я обнаружил, что gcc уже имеет рабочую реализацию std::atomic
, поэтому я хотел попробовать, вот мой пример с использованием Boost Thread 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
в какой-то момент.
EDIT:
Разборка 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