Linux C,如何安排10个等待线程在FIFO中执行?

时间:2018-08-06 20:57:41

标签: c linux multithreading posix threadpool

我正在使用以下条件线程通过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

3 个答案:

答案 0 :(得分:3)

您可能无法使用

pthread_setschedparam,因为它需要特权。您无需检查这些调用的返回值,但可能会发现它们失败并显示EPERM。他们为我这样做。

  

我需要按照到达的顺序解锁线程   到pthread_cond_wait(&cvv,&lock);我需要知道是否可能   或不能保证会出现这种情况。

是的,您可以这样做,但是您需要自己动手。这是一种可以实现的方案:

  • 建立三个全局计数器,例如inoutnext,它们的访问受互斥量保护。将它们全部初始化为0。

  • 每个线程都像这样穿过锁:

    • 在等待CV之前,它会递增in并记录新值。这是它的“门票”。
    • 它测试其票证是否等于next并且next小于或等于out,并且仅在不满足这些条件之一或全部的情况下,才等待CV 。
    • 如果确实等待,则返回时,将循环返回以针对next的当前值测试其票证。
    • 在通过锁之前,它会递增next
    • 最后,它向CV广播(这可能是在解锁互斥锁之前或之后)
  • 解锁下一个线程,

    • 增加out
    • 如果next仍为0,则也将其递增
    • 致电pthread_cond_broadcast pthread_cond_signal

当然,对inoutnext的所有访问都必须在互斥锁的保护下进行,该互斥锁应与CV所使用的相同。

请注意,当当前没有线程被锁定时,该方案允许线程准许授予解锁。这实际上将解决您当前实现的问题之一,但是如果您愿意,您可以仅使用innext重做它,从而使执行解锁的线程等待,直到超过in next。这可以通过使用相同的CV来实现。细节留作练习。

答案 1 :(得分:1)

据我所知,还没有一种特殊的方法可以按顺序排列竞争同一资源的线程。这适用于信号量,我认为也适用于条件变量。操作系统将简单地调度优先级最高的线程争用资源。

因此,您必须具有10个单独的同步原语(信号量,条件变量等),每个原语都用于单个线程。

顺便说一句,您输出的第一部分的良好排序就是好运;绝对没有任何保证可以保证对pthread_create的连续调用实际上会导致新线程在该处运行,然后按该顺序运行。

答案 2 :(得分:0)

十个互斥或信号量怎么样?全部开始锁定。每个线程都等待一个锁,一旦完成工作,它将为下一个线程(n + 1)解锁锁。最后一个线程将解锁第一个锁。

或者,这些线程将仅执行一次,为什么要使用所有线程?如果这是练习的要求,并且最后一个线程的末尾是您的程序的末尾,则在解锁下一个线程的锁之后,线程应退出,并且最后一个线程根本没有要解锁的锁。然后主线程(您的<Route exact path="/account" component={Page1}> <Route path="/new" component={Page2}/> <Route path="/(:userId)" component={Page1}/> </Route> 函数)仅等待(通过.navbar .navbar-menu .navbar-end .has-dropdown .navbar-link:hover { background-color: #3C2148; } )所有线程完成。


线程函数的伪代码:

.navbar .navbar-menu .navbar-end .has-dropdown .navbar-link{
  background-color: #3C2148;
}