Приобретение ресурсов и pthreads - PullRequest
5 голосов
/ 24 января 2011

Я приобретаю некоторые ресурсы в порядке возрастания. Какая версия лучше? Мне сказали, что # 2 приводит к истощению потоков, требующих ресурсов с более высоким номером. Это правда? Если да, то как и почему?

a[] sorted array 

1

for(int i = 1; i < N; ++i) {
  lock(mutex)
  while(!resource_available[a[i]]) {
    pthread_cond_wait(&cond_w[a[i]], &mutex);
  }
  resource_available[a[i]] = 0;
  unlock(mutex)
}

2

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)

EDIT: Оказывается, что порядок, в котором вы высвобождаете ресурсы, имеет значение, а не над конструкциями. Если вы отпустите их, чтобы вы получили их, случится голод, если наоборот, то, вероятно, нет.

Ответы [ 3 ]

3 голосов
/ 24 января 2011

Оба будут практически эквивалентны, так как в примере 1 поток почти всегда будет повторно запрашивать мьютекс, не переходя в спящий режим сразу же после его разблокировки, поскольку между ними вычисляются только два выражения.

2 голосов
/ 24 января 2011

Это вызвало бы большее голодание, когда ресурсы всегда доступны и pthread_cond_wait не нуждается в запуске.В этом случае у вас будет мьютекс всего цикла.Так что, если N очень велико, то, блокируя весь цикл, вы можете голодать другими потоками, которым нужен мьютекс.

Как правило, рекомендуется блокировать самые маленькие области, чтобы избежать голодания других потоков и взаимоблокировок.

Подумайте также, когда кто-то придет поддержать этот цикл.Будет очень просто добавить несколько дополнительных операторов или функций в тело цикла for и создать больше голодания.Сопровождающий может легко пропустить блокировку в коде.Лучше всего предотвратить это, создав функцию, отвечающую за получение ресурса 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);
 }
0 голосов
/ 24 января 2011

У меня будет блокировка и разблокировка в функции resource_available, а затем блокировка только перед ожиданием - разблокировка сразу после нее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...