LINUX.ORG.RU

Вопрос про потоки и мьютексы (си)

 


2

2

Здравствуйте. Скажите пожалуйста...

Есть приложение, в нём несколько потоков (выполняют одну и ту же функцию со своими локальными переменными), эти потоки обращаются к глобальной переменной, но не изменяют её, а только читают. Нужно ли в этом случае ставить pthread_mutex_lock() ?


т.е. это глобальная константа? Или эта переменная не просто число, не атомарна? Если какой-то (основной например) поток ее всё же меняет, я бы от греха подальше защитил ее локом...

I-Love-Microsoft ★★★★★
()

Не обязательно, так как копии переменной скорее всего регистрах будет храниться (если, конечно, она не атомарная).

Upd. На счет изменения переменной в глобальном потоке полностью согласен с оратором выше.

kachsheev ★★★
()
Последнее исправление: kachsheev (всего исправлений: 1)
Ответ на: комментарий от kachsheev

А это безопасно вот так полагаться на особенности архитектуры? Я бы всё-таки защитил. У автора скорее всего не константа, какой-то поток ее меняет, зато оба читают. Все равно ведь если она меняется редко и читается не на каждый чих а например перед началом блока кода, то наличие мьютекса не снизит производительность.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Если, допустим, она меняется редко, то лучше тогда вообще семафоры использовать? Они не так садят производительность.

kachsheev ★★★
()
Ответ на: комментарий от kachsheev

Глобальная int, меняется в основном цикле.

А какие последствия? В момент когда переменная перезаписывается её читает поток, что, кроме получения неверных данных, может произойти?

stD
() автор топика
Ответ на: комментарий от stD

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

kachsheev ★★★
()
Последнее исправление: kachsheev (всего исправлений: 1)
Ответ на: комментарий от stD

Глобальная int, меняется в основном цикле.

А какие последствия? В момент когда переменная перезаписывается её читает поток, что, кроме получения неверных данных, может произойти?

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

И кстати синхронизация фьютексом (мьютексом) конечно эту ситуацию хоть и исправляет — но это как из пушки стрелять по воробьям.

Есть же специально —

memory_order_acquire и memory_order_release

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 1)
Ответ на: комментарий от kachsheev

>это как минимум моветон оставлять её без защиты

Несомненно Вы правы.

А подскажите ещё, что делает флаг -D_REENTRANT при компиляции?

stD
() автор топика

Если переменная не атомарная, то лучше защити мьютексом. Чтобы во время записи никто мусор не прочитал.

Deleted
()
Ответ на: комментарий от Deleted

то лучше защити мьютексом

А мьютекс надо ставить только там где переменная перезаписывается или где читается тоже ставить?

stD
() автор топика
Ответ на: комментарий от unt1tled

сделай ее volatile еще :)

Смешно)

...

Вот бы кто про это подсказал...

А подскажите ещё, что делает флаг -D_REENTRANT при компиляции?

stD
() автор топика

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

invy ★★★★★
()
Ответ на: комментарий от stD

Мне за тебя погуглить? Гугль говорит, что тогда компилятор использует потокобезопасные функции сишных либ. Они есть в двух версиях часто, безопасные и медленные и быстрые и небезопасные.

unt1tled ★★★★
()
Ответ на: комментарий от unt1tled

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

Это я понимаю, не понятно другое, если использовать этот флаг, то можно не пользоваться мьютексами? Или эти «потокобезопасные функции сишных либ» добавляют безопасности?

stD
() автор топика

Если переменная не меняется никаким другим потоком, защищать не надо, если меняется защищать надо всегда, иначе UB (программа ill-formed).

anonymous
()
Ответ на: комментарий от stD

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

anonymous
()
Ответ на: комментарий от anonymous

Переменная меняется только одним потоком...

int count = 0;

void * thread_count_func() 
 { 
   for(;;) 
    { 
      sleep(1);
      count++;
    } 
 } 

Остальные потоки выполняют эту функцию...

void * other_thread_func() 
 { 
   int bla = 0;
   bla = count;
 } 

Дык надо защищать или нет?

stD
() автор топика
Ответ на: комментарий от stD

Атомики придумали не для этого?

anonymous
()
Ответ на: комментарий от stD

Вроде там написано совсем про другое.

anonymous
()
Ответ на: комментарий от stD

Конечно надо. Вот определение гонки:

A data race occurs when: two or more threads in a single process access the same memory location concurrently, and. at least one of the accesses is for writing, and. the threads are not using any exclusive locks to control their accesses to that memory.

У тебя все три пункта: есть потоки + есть общая область в памяти + один из потоков туда пишет. Значит если не защитишь, то будет гонка, а это UB, и его в программе быть не должно.

pftBest ★★★★
()
Ответ на: комментарий от pftBest

Значит если не защитишь, то будет гонка, а это UB, и его в программе быть не должно.

Ты все атомарные переменные блокировками прикрываешь? Типа так надежнее?

Captcha: GIBBS PEATON

anonymous
()
Ответ на: комментарий от pftBest

Твой пруф не про потоки, а только про signal handlers.

Открой глазки шире и посмотри внимательней: «In practice, you can assume that int is atomic. You can also assume that pointer types are atomic; that is very convenient.» :-)

anonymous
()
Ответ на: комментарий от stD

Ну так если ты читаешь, не блокируя, значит и писать в эту переменную одновременно можно, разве не так?

Deleted
()
Ответ на: комментарий от anonymous

Ты все атомарные переменные блокировками прикрываешь? Типа так надежнее?

атомарные переменные используют спец инструкции процессора для чтения и записи (LDREX, STREX) которые выролняют синхронизацию на уровне железа. Для них блокировки не нужны.

pftBest ★★★★
()
Ответ на: комментарий от anonymous

Первая ссылка в гугле, самая первая. Ты бы хоть погуглил

Ты теоретик? :-) Зачем что-то гуглить, если есть официальная документация, в которой сказано, что на практике int - атомарный тип? :-)

anonymous
()
Ответ на: комментарий от anonymous

Может форков() наклепать, а данные через файл перекидавать?

stD
() автор топика
Ответ на: комментарий от anonymous

В стандарте этого нет и есть реальное железо, для которого это будет не так.

Не возражаю :-) Но в доке от GNU сказано: «Both of these assumptions are true on all of the machines that the GNU C Library supports and on all POSIX systems we know of.» :-)

anonymous
()
Ответ на: комментарий от anonymous

А чуть выше написано что это все гарантируется только в контексте signal handler. Может у тебя плохое зрение и ты не видишь приставку sig в слове sig_atomic_t ?

pftBest ★★★★
()
Ответ на: комментарий от pftBest

А чуть выше написано что это все гарантируется только в контексте signal handler. Может у тебя плохое зрение и ты не видишь приставку sig в слове sig_atomic_t ?

Удивительные люди :-) Лол :-) Нет, у меня зрение в норме, в отличии от :-) Ведь у меня не возникает фантазий, контекстов каких-то или сомнений, когда читаю, написанное черным по белому: «In practice, you can assume that int is atomic.» :-) Где ты в этом предложении увидел sig handler, приставку sig, слово sig_atomic_t - мне не ведомо :-)

anonymous
()

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

anonymous
()
Ответ на: комментарий от anonymous

написанное черным по белому

На заборе тоже написано...
Глава 24 из которой ты выдираешь слова без контекста называется
24 Signal Handling
24.4 Defining Signal Handlers
24.4.7 Atomic Data Access and Signal Handling
24.4.7.2 Atomic Types
Как можно тут не заметить слово signal? Есть только два варианта или у тебя избирательная слепота, или ты ничего не читал из этой доки кроме одного предложения.

pftBest ★★★★
()
Ответ на: комментарий от anonymous

В комментариях к вышеупомянутому посту высказана интересная точка зрения. Да, это там где num--. Вот это, если говорить конкретно. Если я верно понимаю то, что написано по ссылке, то инт атомик только в отношении сигналов.

anonymous
()
Ответ на: комментарий от anonymous

Потому что тебе может внезапно прилететь по голове, а ты этого совсем не ожидал.

anonymous
()
Ответ на: комментарий от pftBest

Глава 24 из которой ты выдираешь слова без контекста называется

Глава 24.4.7.2 называется «Atomic Types» :-) Контекстом является «Atomic Types» (в переводе на русский язык - «атомарные типы данных») :-) Там ведётся речь о типе sig_atomic_t :-) В конце там говорится, что «In practice, you can assume that int is atomic.» (в переводе на русский язык - «На практике можете считать int атомарным типом данных» :-)

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

Других вариантов, кроме как то, что int и указатели - атомарные типы на всех машинах, где работает GNU C Library и на всех системах POSIX, с которыми знакомы разработчики GNU C Library, о чём они и говорят: «Both of these assumptions are true on all of the machines that the GNU C Library supports and on all POSIX systems we know of.» :-)

anonymous
()
Ответ на: комментарий от anonymous

Если я верно понимаю то, что написано по ссылке, то инт атомик только в отношении сигналов.

int он и в Африке int :-)

anonymous
()
Ответ на: комментарий от anonymous

Твои пруфы слабоваты, ты сейчас не выглядишь как достойный спора собеседник.

Так а ты не выглядишь вообще никак, и вообще пруфов не приводишь, кроме как рассуждения частных лиц на stackoverflow :-) Но кто бы как не рассуждал, есть официальная документация от GNU :-) Не веришь ей - вводи мьютексы вокруг int :-) Лол :-)

anonymous
()
Ответ на: комментарий от anonymous

Эти частные лица хотя бы приводят аргументацию своим словам, а не «во фразе в документации, вырванной из контекста, написано так, значит всегда так и я прав».

anonymous
()
Ответ на: комментарий от unt1tled

Что такое атомарный тип данных? Атомарными бываю операции. i++ не атомарная операция.

Просто же: атомарный тип данных - это тип данных, любая операция над которым атомарна :-)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.