MVAR 이하와 같은 구조체를 사용하여 C로 구현 될 수
typedef struct{
pthread_cond_t put_cond;
pthread_cond_t take_cond;
pthread_mutex_t lock;
void* value;
} mvar;
put_cond
는 MVAR로부터 값을 위해 대기중인 다른 스레드에 신호를 MVAR 값을 넣어 스레드에 의해 사용된다. take_cond
은 take와 비슷한 기능을합니다. 스케줄링에 대해서는 기본 스케줄링입니다.
value
은 void 포인터입니다. 위의 구조는 MVar에서 모든 유형의 값을 보호하는 데 사용할 수 있습니다. 물론 C는 MVar 외부에서 해당 포인터를 쓸 수있게합니다. 이것은 일어나지 않습니다 (포인터가 MVar 외부로 빠져 나가는 것을 피함으로써 - 항상 MVar 함수를 통해 액세스).
초기화 MVar
:
mvar* newMVar(void* arg){
//create new mvar struct
mvar* var=(mvar*) malloc(sizeof(mvar));
pthread_mutex_init(&var->lock,NULL);
pthread_cond_init(&var->take_cond,NULL);
pthread_cond_init(&var->put_cond,NULL);
var->value = arg;
return (mvar*) var;
}
MVar
빈 - 상기 함수 사용
mvar* newEmptyMVar(){
return newMVar(NULL);
}
putMVar
:
void putMVar(mvar* var,void* value){
pthread_mutex_lock(&var->lock);
while(var->value != NULL)
pthread_cond_wait(&var->put_cond,&var->lock);//if MVar is full, wait until another thread takes the value - release the mutex, and wait on put_cond to become true
var->value = value;//if here, we got the signal from another thread that took MVar - MVar is empty now. OK to fill
pthread_cond_signal(&var->take_cond);//signal other threads that value is available for taking now
pthread_mutex_unlock(&var->lock);
}
takeMVar
:
void* takeMVar(mvar* var){
void* value;
pthread_mutex_lock(&var->lock);
while(var->value == NULL)
pthread_cond_wait(&var->take_cond,&var->lock);//if MVar is empty, wait until another thread fills it - release the mutex, and wait on take_cond to become true
//take the value
value = var->value;
var->value = NULL; //push NULL value to indicate MVar is empty now
pthread_cond_signal(&var->put_cond);//signal other threads that value is available for filling now
pthread_mutex_unlock(&var->lock);
return value; //return the value that was taken from MVar
}
전체 코드는 github이고, example은 MVar 사용법을 보여줍니다.
MVar는 스레드에 액세스하는 스레드가 하나 (무거운 경합) 인 경우 매우 빠릅니다. 그러나 무거운 경합과 여러 스레드 (두 개조차도)에서는 매우 저조한 확장이 가능합니다.이것은 pthreads가 작동하는 방식 때문에 놀랄 일이 아닙니다. 하스켈의 MVar가 여러 스레드에서 매우 잘 작동한다는 것을 알았습니다. GHC에서 가벼운 쓰레드와 동시성 프리미티브가 얼마나 잘 구현되었는지는 놀랄 일이 아닙니다.
출처
2012-01-20 13:13:51
Sal
하스켈의'MVar'에 익숙하지 않은 분들은 [Control.Concurrent.MVar] (http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent-MVar. html) –
나는 당신의 질문에 당신을 도울 수 없다. 그러나 Haskell과 C. 사이의 외침을위한 시간을 어디서 얻었 는가? 어제, 나는 기준을 사용하여 그것을 벤치마킹하는 방법을 배회하고 있었다. – jmg
@jmg, 여기 코드 (haskell-> C) : http://hpaste.org/56609. 벤치마킹 벤치마킹은 매우 간단하지만 결과는 꽤 가깝습니다. C-> Haskell 콜백의 경우이 게시물의 코드를 참조하십시오. http://stackoverflow.com/questions/8902568/runtime-performance-degradation-for-c-ffi-callback-when-pthreads-are-enabled – Sal