2014-09-16 5 views
2

필자는 시스템의 일부 기능이 항상 정의 된 스레드 컨텍스트에서 실행되도록 보장하기 위해 일종의 래퍼를 빨리 작성했습니다. 코드를 가능한 작게 만들기 위해 포인터 할당을 사용하여 스레드가 시작되었는지 확인합니다.포인터 할당을 사용하여 안전하게 스레드 시작을 감지 할 수 있습니까?

void waitForStart() { 
    while (_handler == nullptr) { 
     msleep(100); // Sleep for 100ms; 
    } 
    msleep(100); // Sleep for 100ms to make sure the pointer is assigned 
} 

내 의견으로는 어떤 경우에도 작동합니다. _handler에 대한 할당이 알려지지 않은 경우에도 CPU에서 두 작업으로 분리됩니다.

제 가정은 정확합니까? 또는 이것이 잘못 될 수있는 경우를 놓쳤습니까?

참고로 시스템이 어떻게 보이는지에 대한보다 완전한 예를 들어보십시오. SystemThreadHandler 클래스가 있습니다 :

class Handler { 
public: 
    void doSomeWork() { 
     // things are executed here. 
    } 
}; 

class Thread : public ThreadFromAFramework { 
public: 
    Thread() : _handler(nullptr) { 
    } 
    void waitForStart() { 
     while (_handler == nullptr) { 
      msleep(100); // Sleep for 100ms; 
     } 
     msleep(100); // Sleep for 100ms to make sure the pointer is assigned 
    } 
    Handler* handler() const { 
     return _handler; 
    } 
protected: 
    virtual void run() { // This method is executed as a new thread 
     _handler = new Handler(); 
     exec(); // This will go into a event loop 
     delete _handler; 
     _handler = nullptr; 
    } 
private: 
    Handler *_handler; 
} 

class System { 
public: 
    System() { 
     _thread = new Thread(); 
     _thread->start(); // Start the thread, this will call run() in the new thread 
     _thread->waitForStart(); // Make sure we can access the handler. 
    } 
    void doSomeWork() { 
     Handler *handler = _thread->handler(); 
     // "Magically" call doSomeWork() in the context of the thread. 
    } 
private: 
    Thread *_thread; 
} 
+2

[std :: atomic <>'] (http://en.cppreference.com/w/cpp/atomic/atomic) 또는 ['std :: mutex'] (http : /en.cppreference.com/w/cpp/thread/mutex) 명시 적으로. –

+0

나는 이것을 고려했다. 이렇게하면 CPU가 포인터 액세스 전후에 메모리 액세스를 재정렬하는 것을 방지 할 수 있습니다. 'waitForStart()'메쏘드가 작동하는지 확인하기 위해서 정말로 필요한가? 왜? – Flovdis

+0

'_handler = new Handler();는 원자 적으로 처리되지 않았으며'while (_handler == nullptr)'도 아닙니다. 따라서 뮤텍스 (또는 다른 적절한 동기화 메커니즘)로 읽기 또는 쓰기 액세스를 보호해야합니다. –

답변

1

당신이 잘못 될 수있는 경우를 놓쳤다. 스레드가 포인터를 설정 한 후 5msec 후에 스레드가 종료 될 수 있습니다. 두 스레드에서 변경되는 변수에 액세스하는 것은 동기화 없이는 결코 신뢰할 수 없습니다.

+1

스레드는'exec()'를 호출 한 후 이벤트 루프에 남아 있습니다. 그러므로이 예제에서 스레드는 절대로 종료하지 않으며'delete'도 호출하지 않습니다. 'while' 루프에만 초점을 맞추면, 이것이 잘못 될 수 있습니까? 그리고 왜? – Flovdis

관련 문제