編輯(請注意,省略了並行線程調用的錯誤處理)
您可以通過測試,如果隊列滿了,你在評論中提到的功能實現這一點。對於這個答案,我會假設它是bool is_queue_full(const queue*)
。
在您的測試案例中,您可以通過創建生產者並創建消費者來保證場景3,當且僅當隊列已滿時。像 bool is_queue_full(queue *); //不能使用互斥體本身,也許標誌着它只是實習生使用
struct queue {
/* Actual queue stuff */
pthread_mutex_t queue_mutex;
pthread_cond_t read_condvar;
pthread_cond_t write_condvar;
};
void wait_until_queue_is_full (queue *q) {
pthread_mutex_lock(&q->queue_mutex);
while (!is_queue_full(q)){ //Use in loop because of Spurious wakeups
pthread_cond_wait(&q->write_condvar,&q->queue_mutex);
}
pthread_mutex_unlock(&q->queue_mutex);
}
bool test_writer_woke_up(queue *q);
bool test_case(){
queue *q = create_queue();
producer *p = create_producer(q);
wait_until_queue_is_full(q);
return test_writer_woke_up(q); //or cache the result and destroy your queue, but if your testrunner process will quit anyway...
}
wait_until_queue_is_full
將只檢查隊列已滿,如果沒有,會等待,就像任何讀卡器,直到你的作家又名生產者都有使它充滿。然後你的測試用例可以生成類似於test_writer_woke_up
void intern_consume_stuff(隊列q)的消費者;/您實習生函數,它的東西從隊列中, 但doesen't在意sychronization又名互斥和condvar */
bool test_writer_woke_up(queue *q){
pthread_mutex_lock(&q->queue_mutex); //Could be omitted in this testcase (together with the 1 unlock below of course)
void intern_consume_stuff(queue *q);
pthread_mutex_unlock(&q->queue_mutex); //Could be omitted in this testcase (together with the 1 lock above of course)
pthread_cond_signal(&q->read_condvar);
/* Adjust these as you like to give your producer/writer time to wake up and produce something
*/
unsigned retry_count = 5;
unsigned sleep_time = 1;
//timed cond wait approach
for (; retry_count > 0; --retry_count){
pthread_mutex_lock(&q->queue_mutex);
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += sleep_time;
int timed_cond_rc = 0;
while (!is_queue_full(q) && timed_cond_rc == 0) {
timed_cond_rc = pthread_cond_timedwait(&q->write_condvar, &q->queue_mutex, &ts);
}
if (is_queue_full(q)) {
pthread_mutex_unlock(&q->queue_mutex);
return true;
}
assert(timed_cond_rc == ETIMEDOUT);
continue;
}
return false;
}
如果已經使用了絕對時間等待,因爲你必須重新計算相關計時,或者把事情簡單化,你可以用這種幼稚的做法代替for循環
//naive busy approach
for (; retry_count > 0; --retry_count){
pthread_mutex_lock(q->queue_mutex);
const bool queue_full_result = is_queue_full(q);
pthread_mutex_unlock(q->queue_mutex);
if (queue_full_result){
return true;
} else {
pthread_yield();
sleep(sleep_time);
}
}
只啓動生產者線程,等到它被阻止,然後啓動消費者? – EOF
是否有任何API函數可以讓您只要隊列滿就測試? – Superlokkus
@EOF - 如何以編程方式發現生產者線程現在被阻止? (我正在尋找超出「*等待足夠的時間*」的東西) –