2011-01-21 3 views
1

실제로 필요한 것은 * nix pthread 식별자 (pthread_t)에 대한 휴대용 비교 및 ​​인쇄입니다. pthread_equal 함수는 두 스레드 ID가 같은지 비교하기 위해 존재하지만 일부 구현에서는 pthread_t가 구조체에 대한 포인터이기 때문에 연산자 < < => => (물론 이식 가능함)과 비교할 수 없습니다. 그래서 공유하고 싶은 솔루션을 발견하고 이식성에 대해 논의했습니다.휴대용 인쇄 및 비교 pthread_t

우리는 thred_id 클래스 래퍼를 가지고 있다고 가정합니다.이 래퍼는 덜 유사하고 동등한 비교 가능하며 물론 인쇄 가능해야합니다. 두 개의 부분 특수화를 사용하여 템플릿 클래스를 만듭니다. 하나는 포인터 용이고 다른 하나는 산술 형용입니다.

template <typename T, bool A = is_arithmetic<T>::value> 
struct hash 
{ 
    static unsigned long calculate(T thread_id) 
    { 
     return hash<T*, A>::calculate(&thread_id); 
    } 
}; 

template <typename T> 
struct hash<T*, false> 
{ 
    static unsigned long calculate(T* thread_id) 
    { 
     std::size_t hash = 0; 
     if (char* data = reinterpret_cast<char*>(thread_id)) 
     { 
      for (int i = 0; i < sizeof(T); ++i) 
      { 
       hash = (hash << 6)^(hash >> 26)^data[i]; 
      } 
     } 
     return hash; 
    } 
}; 

template <typename T> 
struct hash<T, true> 
{ 
    static unsigned long calculate(T thread_id) 
    { 
     return static_cast<unsigned long>(thread_id); 
    } 
}; 

어떻게 작동합니까? 우리는 두 개의 스레드 ID를 비교해야하는 경우 우리는 단지

pthread_equal(tid1, tid2); 

하지만 운영자 < 위해 우리는 pthread_t 다음 포인터로 구현됩니다

경우 그래서 여기

hash<pthread_t>::calculate(tid1) < hash<pthread_t>::calculate(tid2) 

을 비교하는 해시 사용을 호출 우리 pointed 객체에 대한 해시를 계산합니다.

산술 형이라면 unsigned int로 캐스트하려고합니다.

구조체로 구현되는 경우 구조체 개체 자체에 대한 해시를 계산합니다.

해시 값은 연산자가 적고 스레드 ID 출력에만 사용됩니다.

당신은 어떻게 생각하십니까? 이 솔루션은 얼마나 이식성이 있으며 더 나은 점이 있습니까?

미리 감사드립니다.

+0

본질적으로 주문할 수없는 유형의 주문을 시행하려는 이유는 무엇입니까? 당신은 개념적으로 무엇을 성취하려고합니까? – FooF

답변

1

pthread_t을 비교하는 대신 스레드 생성을 캡슐화하고 ID가 생성되고 고유 한 map<some_id, pthread_t>에 새 스레드를 추가 할 수 있습니다. 그런 다음 ID로 스레드를 항상 참조하고 원하는대로 정렬하고 정렬하여 비교할 수 있습니다.

+0

실제로 컨테이너에 스레드를 저장할 필요가 없습니다. 연관 컨테이너에 저장하고 비교 및 ​​인쇄 할 수있는 thread_id 래퍼를 작성해야합니다. 당연히 나는 쓰레드 생성과 핸들러를 글로벌 맵에 저장할 수있다. 그러나 그것은 내가 찾고있는 해결책이 아니다. 대부분의 경우 pthread_t는 시스템 내 쓰레드를 유일하게 나타내는 예술적 가치이며 나는 좋아하지 않을 것이다. 대리 ID를 사용하는 것. – axe

0

pthread_t의 데이터 유형은 표준으로 고정되어 있지 않으므로 pthread_compare()이 제공됩니다.

내 사과에서는 pthread_t를 몇 가지 고유 ID로 매핑합니다 (Mark가 제안한 것처럼).

표준이 불투명 유형을해야 말한다 here

+1

나는 그것이 고쳐지지 않는다는 것을 안다. 그게 내가 풀려고하는거야. 함수 pthread_compare가 없다. pthread_equal이 있는데, 이는 두 개의 스레드 ID가 같은지 검사한다. 필자가 말하고자하는 것은 POSIX가 제공하지 않는 연산자 (<연산자)가 적기 때문에 몇 가지를 만들려고합니다. – axe

1

가 pthread_t 반드시 또한 스칼라 데이터 타입이다 참조, 그것은 구조체 또는 노동 조합 또는 비트 필드 수 있습니다.

그 외에도 스칼라 pthread_t를 포함한 pthread_t에는 해시 결과에 영향을 미치는 '노이즈'를 발생시키는 패딩 비트가 포함될 수 있습니다. 현재 사용자 수준에서 pthread_t를 비교하는 보편적 인 이식성 방법은 없습니다.

사실, pthread_t가 포인터 인 시스템의 pthread_equal은 두 arg가 실제로 다른 스레드를 참조하더라도 equality를 반환 할 수 있습니다. 스레드는 종료 할 수 있으며 동일한 포인터 값을 갖는 pthread_t 값을 갖는 새로운 스레드가 작성 될 수 있습니다.

지도가 1 : n 일 수 있기 때문에 역방향 조회를 수행 할 필요가 없다면 매핑 된 고유 ID 기술이 작동합니다. 계속해서 스레드를 종료하고 생성하면지도가 매우 커집니다.