Замедляют ли 2 потока, взаимодействующих друг с другом? - PullRequest
0 голосов
/ 22 декабря 2011

Это очень концептуальный вопрос.

Допустим, у меня есть 2 отдельные темы.Поток A постоянно получает время и сохраняет его как переменную, а поток B постоянно получает время из переменной потока B и что-то с ней делает.

В тот момент, когда поток B обращается к переменной в потоке A, останавливается ли поток A до завершения операции?

Чтобы развернуть, что, если у вас было 3 потока, поток A для получения текущеговремя и установить его как переменную в потоке B, а затем поток C, чтобы прочитать переменную.

Если поток A находится в процессе присвоения переменной в тот момент, когда поток C читает ее, останавливается ли поток до завершения A?

Спасибо за отличные ответы, но теперь яесть еще 1 вопрос.Если они будут мешать, каково предпочтительное решение, чтобы несколько потоков не конкурировали при обмене данными.(Концептуально), что бы вы сделали, чтобы эти потоки могли совместно использовать значение переменной, оставаясь при этом максимально быстрыми индивидуально?

Ответы [ 5 ]

4 голосов
/ 22 декабря 2011

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

Однако, что усложняет это и на самом деле вызывает замедление, так это кеши процессора: чтобы два потока, работающие на разных ЦП, могли обращаться к одному и тому же фрагменту памяти и «видеть» изменения друг друга, кеши ЦП должны быть синхронизированы. , что может полностью свести на нет (массивные) преимущества скорости этих кэшей, если это происходит много.

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

3 голосов
/ 22 декабря 2011

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

Надеюсь, я правильно понял вопрос.

1 голос
/ 22 декабря 2011

Это не приведет к тому, что нить B замедлит нить A.

Но:
1. Нить A может замедлить нить B.В зависимости от архитектуры системы (ядра и кэши) каждая запись потоком A будет очищать строку кэша от ЦП потока B.Следующее чтение B будет более дорогим.
2. Если вы используете блокировку для защиты структуры данных, оба потока должны ее получить.Тогда, очевидно, поток A замедлится.
3. Если вы не используете блокировку и ваш тип данных не атомарный, вы можете прочитать поврежденные данные.Например, если время изменяется с 0x0000ffff на 0x00010000, вы можете прочитать 0x0001ffff.Обычно целое число, выровненное на 4 байта, является атомарным, поэтому, если ваше время равно time_t, вы, вероятно, в порядке.Но детали зависят от платформы.

0 голосов
/ 22 декабря 2011

Да, они замедляются.

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

и даже если у вас нет проверок параллелизма, я почти уверен, что память не допускает одновременного чтения или чтения / записи: поскольку такая ситуация может возникнуть, тем не менее ваши потоки будут вынуждены немного замедлиться

0 голосов
/ 22 декабря 2011

Это зависит от ОС и количества процессоров, но в основном да, когда один поток работает, другой ждет.Не имеет большого значения, использует ли поток B переменную, используемую потоком A, поскольку они совместно используют одну и ту же память.

...