簡體   English   中英

Linux C,如何安排10個等待線程在FIFO中執行?

[英]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, &param);
    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);的順序解鎖線程。 我需要知道這是否可行,還是不能保證有這種情況。

是的,您可以這樣做,但是您需要自己動手。 這是一個可以實現它的方案:

  • 建立三個全局計數器,例如inoutnext ,對它們的訪問受互斥量保護。 將它們全部初始化為0。

  • 每個線程都像這樣穿過鎖:

    • 等待的簡歷之前,增加in並記錄新值。 這是它的“門票”。
    • 它會測試其票證是否等於nextnext小於或等於out ,並且僅在不滿足這兩個條件之一或全部的情況下等待CV。
    • 如果確實等待,則返回時將循環返回以針對next的當前值測試其票證。
    • 在通過鎖之前,它會先增加next
    • 最后,它會向CV廣播(這可能是在解鎖互斥鎖之前或之后)
  • 解鎖下一個線程,

    • 增加out
    • 如果next仍然為0,則也將其遞增
    • 調用pthread_cond_broadcast不是 pthread_cond_signal

當然,對inoutnext所有訪問都必須在互斥量的保護next進行,該互斥量應與CV相同。

請注意,當當前沒有線程鎖定時,該方案允許線程准許授予解鎖。 這實際上將解決當前實現中的問題之一,但是如果您願意,則可以僅使用innext對其進行重做,使執行解鎖操作的線程等待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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM