Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 资源获取和pthreads_C_Resources_Pthreads - Fatal编程技术网

C 资源获取和pthreads

C 资源获取和pthreads,c,resources,pthreads,C,Resources,Pthreads,我正在按顺序获取一些资源。哪个版本更好?我被告知#2会导致需要更高编号资源的线程的匮乏。这是真的吗?如果是,如何以及为什么 a[] sorted array 一, for(int i=1;i

我正在按顺序获取一些资源。哪个版本更好?我被告知#2会导致需要更高编号资源的线程的匮乏。这是真的吗?如果是,如何以及为什么

a[] sorted array 
一,

for(int i=1;i
二,

锁(互斥)
对于(int i=1;i
编辑:
事实证明,释放资源的顺序是不同的,而不是在构造之上。如果您按接收它们的顺序释放它们,则会发生饥饿,如果相反,则可能不会。

当资源始终可用且pthread cond\u wait不需要运行时,会导致更多饥饿。在这种情况下,整个循环都有互斥锁。因此,如果N非常大,那么通过在整个循环外部锁定,您可能会使其他需要互斥锁的线程处于饥饿状态

通常,最好锁定最小的区域nescesarry,以避免其他线程不足和死锁

当有人来维护这个循环时,也要考虑一下。很容易在for循环体中全局调用一些额外的if语句/函数调用,并创建更多的饥饿。维护人员可能很容易错过代码中的锁定。最好通过创建一个负责获取资源i的函数来防止这种情况。此函数将负责所有锁定,消除调用代码扩展关键部分大小的任何机会

 // blocks till resource resourceNum is obtained
 void acquire_resource(int resourceNum)
 {
     lock(mutex)
     while(!resource_available[a[i]]) {
       pthread_cond_wait(&cond_w[a[i]], &mutex);
     }
     unlock(mutex)
 }

 for(int i = 1; i < N; ++i) {
     acquire_resource(i);
 }
//阻塞,直到获得资源resourceNum
无效获取资源(int resourceNum)
{
锁(互斥)
而(!资源_可用[a[i]]){
pthread_cond_wait(&cond_w[a[i]],&mutex);
}
解锁(互斥)
}
对于(int i=1;i
两者实际上是等价的,因为在示例1中,线程几乎总是在解锁互斥锁后立即重新获取互斥锁,而不会立即休眠,因为在这两者之间只有两个表达式求值。

我将在
资源\u中提供锁定和解锁功能,然后只在等待之前锁定-在等待之后解锁。

但是pthread\u cond\u wait释放互斥锁,或者线程成功获取所有资源,然后释放互斥锁。我不知道饥饿是如何发生的,但N是有限的(在我的例子中是100以下),如果所有资源都可用,它会在有限的时间内完成,所以等待互斥的线程最终得到它。N可能是有限的,但您的代码维护人员可以通过在循环中添加更多代码来扩展关键部分的大小。参见我的编辑——通过在函数调用中包装锁,您可以帮助维护人员通过清楚地描述两段代码的责任来避免这种情况。一种是阻塞直到获得一个资源,另一种是尝试获取所有N个资源。问题是#2中是否会发生饥饿。代码不会被维护,所以不用担心。那里不应该有一个acquire\u resource(a[i])调用吗?饥饿的定义你能解释为什么在#2中没有人会挨饿吗?@niteria:证明一个否定的答案是出了名的困难。这将取决于线程除了这个循环之外做了什么——它们是否花费了大量时间不保存任何资源?然而,我可以说,您给出的两个循环是等价的——解锁互斥锁并不意味着屈服,互斥锁服务人员也不会排队。您是对的,问题在于释放资源的顺序。你知道为什么相反的顺序有用吗?
lock(mutex)
for(int i = 1; i < N; ++i) {
  while(!resource_available[a[i]]) {
    pthread_cond_wait(&cond_w[a[i]], &mutex);
  }
  resource_available[a[i]] = 0;
}
unlock(mutex)
 // blocks till resource resourceNum is obtained
 void acquire_resource(int resourceNum)
 {
     lock(mutex)
     while(!resource_available[a[i]]) {
       pthread_cond_wait(&cond_w[a[i]], &mutex);
     }
     unlock(mutex)
 }

 for(int i = 1; i < N; ++i) {
     acquire_resource(i);
 }