[英]Linux C, How to schedule 10 waiting threads to execute in FIFO?
我正在使用以下條件線程通過FIFO調度鎖定10個線程,我需要按照到達pthread_cond_wait(&cvv,&lock);的順序解鎖線程。 我需要知道這是否可行,還是不能保證有這種情況。
struct sched_param param = {.sched_priority = 10};
pthread_cond_t cvv = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
void *thread(void *v) {
pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
int index = *((int *)v);
printf("Locking [%d] and waiting\n", index);
pthread_mutex_lock(&lock);
pthread_cond_wait(&cvv, &lock);
printf("Unlockd [%d] => %d\n", index, clock());
pthread_mutex_unlock(&lock);
return NULL;
}
int main(int argc, char** argv) {
for (int i = 0; i < 10; i++) {
t = (pthread_t *) malloc(sizeof (pthread_t));
int *x = malloc(sizeof (int));
*x = i;
pthread_create(t, NULL, thread, x);
}
for (int i = 0; i < 10; i++) {
pthread_cond_signal(&cvv);
}
}
產量未按升序排列
Locking [0] and waiting
Locking [1] and waiting
Locking [2] and waiting
Locking [3] and waiting
Locking [4] and waiting
Locking [5] and waiting
Locking [6] and waiting
Locking [7] and waiting
Locking [8] and waiting
Locking [9] and waiting
Unlocked [0] => 7043
Unlocked [8] => 7084
Unlocked [6] => 7100
Unlocked [2] => 7130
Unlocked [5] => 7294
Unlocked [7] => 7362
Unlocked [3] => 7407
Unlocked [1] => 7463
Unlocked [9] => 7482
Unlocked [4] => 7559
pthread_setschedparam
可能不可用,因為它需要特權。 您無需檢查這些調用的返回值,但可能會發現它們在EPERM
上失敗。 他們為我這樣做。
我需要按照到達pthread_cond_wait(&cvv,&lock);的順序解鎖線程。 我需要知道這是否可行,還是不能保證有這種情況。
是的,您可以這樣做,但是您需要自己動手。 這是一個可以實現它的方案:
建立三個全局計數器,例如in
, out
和next
,對它們的訪問受互斥量保護。 將它們全部初始化為0。
每個線程都像這樣穿過鎖:
in
並記錄新值。 這是它的“門票”。 next
和next
小於或等於out
,並且僅在不滿足這兩個條件之一或全部的情況下等待CV。 next
的當前值測試其票證。 next
。 解鎖下一個線程,
out
next
仍然為0,則也將其遞增 pthread_cond_broadcast
( 不是 pthread_cond_signal
) 當然,對in
, out
和next
所有訪問都必須在互斥量的保護next
進行,該互斥量應與CV相同。
請注意,當當前沒有線程鎖定時,該方案允許線程准許授予解鎖。 這實際上將解決當前實現中的問題之一,但是如果您願意,則可以僅使用in
和next
對其進行重做,使執行解鎖操作的線程等待in
超過next
。 這可以通過使用相同的CV來實現。 細節留作練習。
據我所知,還沒有一種特殊的方法可以按順序排列爭用同一資源的線程。 這適用於信號量,我認為也適用於條件變量。 操作系統將簡單地調度哪個優先級最高的線程首先爭用資源。
因此,您必須具有10個獨立的同步原語(信號量,條件變量等),每個原語用於單個線程。
順便說一句,您輸出的第一部分的良好排序就是好運; 絕對沒有任何保證可以保證對pthread_create的連續調用實際上會導致新線程在該處運行,然后按該順序運行。
十個互斥或信號量怎么樣? 全部開始鎖定。 每個線程都等待一個鎖,一旦完成工作,它將為下一個線程(n + 1)解鎖鎖。 最后一個線程將解鎖第一個鎖。
或者,這些線程中只能執行一次,為什么要完全使用線程? 如果這是練習的要求,並且最后一個線程的末尾是您的程序的末尾,則在解鎖下一個線程的鎖之后,線程應退出,並且最后一個線程根本沒有要解鎖的鎖。 然后,主線程(您的main
函數)僅等待(通過pthread_join
)所有線程完成。
線程函數的偽代碼:
void *function(void *)
{
wait(lock[n]);
// Do work...
unlock(lock[n + 1]);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.