2011-12-14 4 views
0

그래서 gcc가 이미 std::atomic의 작업 구현을 가지고 있다는 것을 발견 그래서 내가 여기 부스트 스레드 1.48 std::atomic 사용하여 내 예입니다, 그것을 밖으로 시도 싶어 : running가 남아있는 동안 지금mingw 4.6.1 원자 실패?

#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; 
} 

true 모두 잘하지만 때 사용자가 quit을 입력하고 runningfalse 일부 스레드 끝으로 설정되고 일부는 그렇지 않습니다. 이것은 최적화의 유무에 관계없이 발생합니다. 이것은 의도 한대로 작동합니까? 원자학에 대한 나의 이해에서 읽기가 하나의 쓰기와 충돌해서는 안되기 때문에 스레드는 어느 시점에서 running=false을 볼 수 있습니다.

EDIT : FUNC1의 분해 :와 Mingw 컴파일 분해 프로그램, 프로그램 으로서는

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  
+1

일반 GCC에서 제대로 작동합니다. 'func1'을 해체 할 수 있습니까? – Cubbi

답변

1

, 원자로서 running 취급하지 않는다 : 그것은 동기화없이 일정한 mov 0x8(%ebp),%eax 탑재된다.

_ZN6Server5func1Ev:  // Server::func1() 
    jmp  .L78 
.L79: 
    // do stuff 
.L78: 
    mfence 
    movzbl (%rdi), %eax // load from `running` 
    mfence 
    testb %al, %al 
    jne  .L79 
    ret 

하나와 Mingw은 아직 지원하지 않습니다, 또는 뭔가 구성에서 누락되었습니다

리눅스/x86_64에에 GCC-4.6.2의 출력과 비교.

+0

이 문제가 신속하게 해결되는지 궁금합니다. 나는 이것을 제외하고 이것과 관련된 것을 찾을 수 없다. [link] (http://sourceforge.net/tracker/?func=detail&atid=102435&aid=3420359&group_id=2435) – KayelGee