[ CnUnix ] in KIDS 글 쓴 이(By): 구르미 (구르미) 날 짜 (Date): 2005년 3월 26일 토요일 오전 12시 31분 47초 제 목(Title): pthread에서 suspend, continue Solaris thread는 thr_suspend(), thr_continue()를 제공하고 Windows에서도 비슷한게 있지만 POSIX thread spec에는 없는 걸로 알고 있습니다. 어쩔 수없이 condition variable을 이용해서 만들어 쓰고 있습니다. 다소 허접한 코드지만 벌레는 없을 겁니다. -- #define CB_SIZE 8 // at your convenience typedef struct cb_type { pthread_cond_t thr_cond; pthread_mutex_t thr_lock; struct cb_type *next; unsigned int ok; } cb_t; // code block type cb_t *cb, *cb_first, *cb_last; pthread_mutex_t cblk=PTHREAD_MUTEX_INITIALIZER; unsigned int cb_cnt; static void cb_init() { int i; cb = (cb_t *) malloc(sizeof(cb_t) * CB_SIZE); for(i=0;i < CB_SIZE;i++) { pthread_mutex_init( &(cb[i].thr_lock), NULL); pthread_cond_init( &(cb[i].thr_cond), NULL); if(i < CB_SIZE-1) cb[i].next = &cb[i+1]; else cb[i].next = NULL; cb[i].ok = 1; } cb_first = &cb[0]; cb_last = &cb[CB_SIZE-1]; cb_cnt = CB_SIZE; } cb_t * cb_alloc() { int i; cb_t *new_cb = (cb_t *) malloc( sizeof(cb_t) * CB_SIZE); for(i=0;i < CB_SIZE ;i++) { pthread_mutex_init( &(new_cb[i].thr_lock), NULL); pthread_cond_init( &(new_cb[i].thr_cond), NULL); if(i<CB_SIZE-1) new_cb[i].next = &new_cb[i+1]; else new_cb[i].next = NULL; new_cb[i].ok = 1; } cb_last = &new_cb[CB_SIZE-1]; cb_cnt += CB_SIZE; return new_cb; } cb_t * get_cb() { cb_t *c; pthread_mutex_lock(&cblk); if(!cb_first) cb_first = cb_alloc(); c = cb_first; cb_first = cb_first->next; c->next = NULL; pthread_mutex_unlock(&cblk); return c; } void put_cb(cb_t *cb) { pthread_mutex_lock(&cblk); cb->next = cb_first; cb_first = cb; pthread_mutex_unlock(&cblk); } void thr_continue(cb_t *cb) { pthread_mutex_lock( &(cb->thr_lock) ); cb->ok = 0; pthread_cond_signal( &(cb->thr_cond) ); pthread_mutex_unlock( &(cb->thr_lock) ); } void thr_suspend(cb_t *cb) { pthread_mutex_lock( &(cb->thr_lock) ); while(cb->ok) { pthread_cond_wait( &(cb->thr_cond), &(cb->thr_lock) ); } cb->ok = 1; pthread_mutex_unlock( &(cb->thr_lock) ); put_cb(cb); } --- usage example in message layer thread. --- void send_msg_and_wait(int pe) { msg_t *m; cb_t *cb; cb = get_cb(); m = msg_alloc(); m->cb = cb; send_msg(pe, m);// send message thr_suspend(); // wait } void recv_msg_and_wake_up(void *m) { msg_t *msg=(msg_t *)m; thr_continue(msg->sb); // wake up the suspended thread. } --- |