2010-07-28 4 views
1

프로세스 내에서 여러 스레드를 실행하려고합니다. 스레드간에 메시지를 전달할 수있는 가장 효율적인 방법을 찾고 있습니다.최적의 다중 스레드 메시지 큐 찾기

각 스레드는 공유 메모리 입력 메시지 버퍼를 갖습니다. 다른 스레드는 적절한 버퍼를 작성합니다.

메시지가 우선합니다. 이 과정을 직접 관리하고 싶습니다.

값 비싼 잠금 또는 동기화를 사용하지 않고이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 아니면 이미 입증 된 라이브러리가 있습니까? (델파이, C 또는 C# 괜찮아요).

답변

2

이 이미

을 :) 만들어 다른 사람들이 Intel Threading Building Blocks를 살펴 보자 많은 실수를 반복하지 않고 제대로하기 어렵다 - 라이브러리는 몇 가지 잘 설계 큐 템플릿 (및 기타 컬렉션)가 당신을 귀하의 목적에 가장 적합한 것을 테스트하고 볼 수 있습니다.

+0

감사합니다. Nikolai :) – IamIC

1

여러 스레드로 작업하는 경우 동기화를 피하기 어렵습니다. 다행히도 그리 어렵지 않습니다.

단일 프로세스의 경우 중요한 섹션이 주로 선택되는 경우가 많습니다. 빠르고 사용하기 쉽습니다. 단순화를 위해, 나는 초기화와 정리를 다루기 위해 보통 그것을 클래스로 감싼다.

잠금/잠금 해제 할 수있는 "자동 잠금"클래스를 사용하면 더 간단하게 만들 수 있습니다.

class CTkAutoLock 
{ 
public: 
    CTkAutoLock(CTkCritSec &lock) 
    : m_lock(lock) 
    { 
     m_lock.Lock(); 
    } 
    virtual ~CTkAutoLock() 
    { 
     m_lock.Unlock(); 
    } 
private: 
    CTkCritSec &m_lock; 
}; 

어디서나 잠금을 설정하려는 위치에서 자동 잠금을 인스턴스화합니다. 기능이 끝나면 잠금이 해제됩니다. 또한 예외가있는 경우 자동으로 잠금이 해제됩니다 (예외 안전성 제공).

이제는 cmsg의 내용은 당신이 좋아하는 무엇이든 할 수있다

#include <queue> 
#include <deque> 
#include <functional> 
#include <string> 

struct CMsg 
{ 
    CMsg(const std::string &s, int n=1) 
    : sText(s), nPriority(n) 
    { 
    } 
    int   nPriority; 
    std::string sText; 

    struct Compare : public std::binary_function<bool, const CMsg *, const CMsg *> 
    { 
     bool operator() (const CMsg *p0, const CMsg *p1) 
     { 
      return p0->nPriority < p1->nPriority; 
     } 
    }; 
}; 

class CMsgQueue : 
     private std::priority_queue<CMsg *, std::deque<CMsg *>, CMsg::Compare > 
{ 
public: 
    void Push(CMsg *pJob) 
    { 
     CTkAutoLock lk(m_critSec); 
     push(pJob); 
    } 
    CMsg *Pop() 
    { 
     CTkAutoLock lk(m_critSec); 

     CMsg *pJob(NULL); 
     if (!Empty()) 
     { 
      pJob = top(); 
      pop(); 
     } 
     return pJob; 
    } 
    bool Empty() 
    { 
     CTkAutoLock lk(m_critSec); 

     return empty(); 
    } 

private: 
    CTkCritSec m_critSec; 
}; 

성병 우선 순위 큐에서 간단한 메시지 큐를 만들 수 있습니다. CMsgQue는 개인적으로에서 std :: priority_queue를 상속받습니다. 이를 통해 우리의 (동기화 된) 메소드를 거치지 않고 대기열에 대한 원시 액세스를 방지합니다.

각 스레드에 이와 같은 큐를 지정하면됩니다.

면책 조항 여기 코드는 설명의 요지를 빠르게 나타냅니다. 프로덕션 환경에서 사용하기 전에 오류가 있으며 검토 및 테스트가 필요할 수 있습니다.

+0

감사합니다. Michael! 잠금 장치가 필요없는 ASM을 사용하는 솔루션을 보았습니다! 나는 그것이 닷넷에서 가능하다고 생각하지 않는다. – IamIC

+0

@IanC 자물쇠 없이는 어떻게 할 수 있는지 모르겠습니다. 나는 ASM 코드가 자물쇠 자체를하고 있다고 생각한다. 두 개의 스레드가 잠금없이 동시에 큐에 액세스하려고하면 잘못된 일이 발생합니다. :-(연동 된 *() 함수를 사용하여 잠금을 설정할 수 있지만 일반적으로 중요한 섹션을 사용하는 것보다 쉽지는 않습니다. –

+0

내 컴퓨터에서 초당 2 백만 회 잠금 및 잠금 해제가 가능합니다. 하지만 원자 ASM 함수를 사용하면 두 번째 방법 (cmpxchg 사용)에서 2 천만 개를 초과하는 잠금/잠금 해제를 수행 할 수 있으므로 두 방법간에 상당한 차이가 있어야합니다. – IamIC