C++ 클래스의 멤버로 스레드를 시작하는 가장 좋은 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/86046

  •  01-07-2019
  •  | 
  •  

문제

나는 궁금하다 최상의 C++ 클래스의 멤버인 pthread를 시작하는 방법은 무엇입니까?내 자신의 접근 방식은 답변으로 다음과 같습니다 ...

도움이 되었습니까?

해결책

나는 보통 클래스의 정적 멤버 함수를 사용하고 클래스에 대한 포인터를 void * 매개변수로 사용합니다.그런 다음 해당 함수는 스레드 처리를 수행하거나 클래스 참조를 사용하여 다른 비정적 멤버 함수를 호출할 수 있습니다.그러면 해당 함수는 어색한 구문 없이 모든 클래스 멤버를 참조할 수 있습니다.

다른 팁

이는 다음과 같이 Boost 라이브러리를 사용하여 간단하게 수행할 수 있습니다.

#include <boost/thread.hpp>

// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}

// construct an instance of the widget modeller or controller
cWidget theWidget;

// start new thread by invoking method run on theWidget instance

boost::thread* pThread = new boost::thread(
    &cWidget::Run,      // pointer to member function to execute in thread
    &theWidget);        // pointer to instance of class

노트:

  • 이는 일반 클래스 멤버 함수를 사용합니다.클래스 인터페이스를 혼란스럽게 하는 추가 정적 멤버를 추가할 필요가 없습니다.
  • 스레드를 시작하는 소스 파일에 Boost/thread.hpp를 포함시키면 됩니다.방금 부스트로 시작했다면 크고 위협적인 패키지의 나머지 부분은 모두 무시할 수 있습니다.

C++11에서는 동일한 작업을 수행할 수 있지만 부스트는 사용하지 않습니다.

// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}

// construct an instance of the widget modeller or controller
cWidget theWidget;

// start new thread by invoking method run on theWidget instance

std::thread * pThread = new std::thread(
    &cWidget::Run,      // pointer to member function to execute in thread
    &theWidget);        // pointer to instance of class

void* 매개변수를 사용하여 부트스트랩해야 합니다.

class A
{
  static void* StaticThreadProc(void *arg)
  {
    return reinterpret_cast<A*>(arg)->ThreadProc();
  }

  void* ThreadProc(void)
  {
    // do stuff
  }
};

...

pthread_t theThread;
pthread_create(&theThread, NULL, &A::StaticThreadProc, this);

저는 위에서 설명한 세 가지 방법을 사용했습니다.C++에서 처음 스레딩을 사용했을 때 나는 다음과 같이 사용했습니다. 정적 멤버 함수, 그 다음에 친구 기능 그리고 마지막으로 부스트 라이브러리.현재 저는 BOOST를 선호합니다.지난 몇 년 동안 나는 꽤 BOOST 편협한 사람이 되었습니다.

BOOST는 C++에 대한 것이며 CPAN은 Perl에 대한 것입니다.:)

Boost 라이브러리는 사본 메커니즘을 제공하여 객체 정보를 새 스레드로 전송하는 데 도움이됩니다.다른 부스트 예제에서는 Boost::bind가 포인터와 함께 복사되며 이 역시 복사됩니다.따라서 매달린 포인터를 방지하려면 객체의 유효성을 주의 깊게 살펴봐야 합니다.Operator()를 구현하고 대신 복사 생성자를 제공하고 객체를 직접 전달하면 신경 쓸 필요가 없습니다.

많은 문제를 방지하는 훨씬 더 좋은 솔루션입니다.

#include <boost/thread.hpp>

class MyClass {
public:
        MyClass(int i);
        MyClass(const MyClass& myClass);  // Copy-Constructor
        void operator()() const;          // entry point for the new thread

        virtual void doSomething();       // Now you can use virtual functions

private:
        int i;                            // and also fields very easily
};

MyClass clazz(1);
// Passing the object directly will create a copy internally
// Now you don't have to worry about the validity of the clazz object above
// after starting the other thread
// The operator() will be executed for the new thread.
boost::thread thread(clazz);             // create the object on the stack

다른 부스트 예제는 힙에 스레드 개체를 생성하지만 그렇게 하는 것은 의미가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top