Синхронизировать несколько потоков в - PullRequest
0 голосов
/ 09 июня 2018

Я открываю библиотеку pthread (в C) и у меня возникают проблемы с пониманием нескольких вещей.

Прежде всего, я понимаю, что такое мьютекс, я понимаю, как он работает,хорошо, я также понимаю концепцию cond, но мне не удается правильно ее использовать (я не совсем понимаю, как объединить мьютекс и cond)

Это в псевдокоде, что я хочу сделать:

thread :
    loop :
        // do something
    end loop
end thread

Таким образом, существует n потоков, но каждый поток использует одну и ту же функцию.Я хочу, чтобы внутренняя часть цикла выполнялась параллельно всеми потоками, НО каждый поток должен находиться в одной и той же итерации цикла. Это означает, что мне все равно, в каком порядке выполняются инструкции внутри цикла между потоками, ноначать итерацию 2 потока, все другие потоки должны завершить итерацию 1 (и т. д.).Итак, мой вопрос: как ты это делаешь?Не особенно в конкретном примере, но теоретически.

РЕДАКТИРОВАТЬ

Мне удается это сделать, я не знаю, правильно ли это, но это работает:

global nbOfThreads
global nbOfIterations

thread :
    lock(mutex0)
    unlock(mutex0)
    loop :
        // Do something
        lock(mutex1)
        nbOfIterations++
        if (nbOfIterations == nbOfThread) :
            nbOfIterations = 0
            broadcast(cond)
            unlock(mutex1)
            continue
        end if

        wait(cond, mutex1)
        unlock(mutex1)
    end loop
end thread

main (n) :
    nbOfThreads = n
    nbOfIterations = 0
    lock(mutex0)
    do nbOfThreads times : create(thread) 
    unlock(mutex0)
end main


Я, очевидно, пытался понять себя, но есть некоторые вещи, которые я не понимаю:

  • Основная причина: ПОЧЕМУ нужно условие?пара с мьютексом
  • В некоторых примерах я видел что-то вроде этого:
// thread A :
while (!condition)
    wait(&cond)

// thread B :
if (condition)
    signal(&cond)

ну, я действительно не понимаю смысла в этом цикле while, я думал, подожди, поставьПоток в паузе, пока условие не выполнится (пока другой поток не отправит сигнал).Я имею в виду, я бы получил это, если бы это было, а не какое-то время.

Спасибо

Ответы [ 2 ]

0 голосов
/ 09 июня 2018

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

В зависимости от вашей задачи может быть проще использовать другой примитив синхронизации, такой как барьер (см. pthread_barrier_init) или семафор (sem_init).использовать.

0 голосов
/ 09 июня 2018

ПОЧЕМУ нужно условие cond .... потому что (! Условие), на которое вы ссылаетесь, почти наверняка зависит от того, какие биты объекта не меняются, когда вы ссылаетесь на них.Соответственно, изменение состояния объекта должно быть сделано таким образом, чтобы любой атом наблюдался атомарно;таким образом мьютекс.В то время как вы могли бы полагаться на слишком умные наполовину хакерские атаки, такие как атомарные типы, существует также проблема «что, если он был изменен сразу после того, как вы проверили его» - условие гонки.Таким образом, идиоматическая блокировка ();while (! cond) {wait ();}.

Точка времени ... Сигнал + ожидание не является передачей управления;после сигнала с объектом может произойти любое количество вещей, прежде чем конкретный поток вернется из ожидания.Даже если условие могло быть в правильном состоянии, к тому времени, как поток A его проверяет, оно может перестать быть.В момент выхода из цикла while поток A знает: условие находится в желаемом состоянии, и у меня есть эксклюзивный доступ к объекту.

...