2013-12-23 6 views
2

У меня есть два потока: THREAD 1 и THREAD 2. Я просто хотел общаться между ними. THREAD 1 содержит значение, которое хранится в указателе, а THREAD 2 - это значение указателя, которое будет доступно для этого потока.Связь между потоками без IPC

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

Прокомментируйте это. Каков наилучший способ и почему ...?

+2

Как насчет двух банок со строкой между ними? ;-) –

+0

Кстати, вы, вероятно, будете использовать inter- * thread * синхронизацию, а не межпрограммную * связь! Поскольку потоки разделяют одно общее адресное пространство, связь является «бесплатной» ... –

ответ

8

Два потока могут получить доступ к одной и той же переменной, это нормально. Просто остерегайтесь synchronization issues. Если оба потока записывают значение, есть возможность race condition. Если какой-либо поток записывает значения non-atomically (так что значение данных не всегда находится в постоянном состоянии), есть вероятность, что другие потоки будут считывать значение, пока оно находится в недействительном промежуточном состоянии. Эти ситуации необходимо обрабатывать с помощью примитивов синхронизации, таких как mutexes, semaphores и т. Д.

+0

Это действительно приятно.Но рассмотрим случай, когда THREAD 1 записывает значение в указатель, а THREAD 2 только читает его. В таком случае, будет ли мое предложение работать? –

+2

В этом случае вопрос * what * имеет значение, если это указатель на сложный тип, вы можете найти частичное состояние записи (это ваша запись * atomic *). Безопаснее просто использовать мьютекс для синхронизации доступа к ресурс. Как правило, если у вас есть сложный тип, вы можете добавить mutex * к * вашему типу, другому члену структуры и работать над этим, без необходимости пропускать второй указатель. –

+1

@RajanChennai: только одновременные операции чтения безопасны без синхронизации! – alk

2

Прочитано posix threads tutorial. Тогда вы поймете, почему на практике так важно использовать примитивы синхронизации (по крайней мере, чтобы получить понятное поведение из вашей программы).

Любые данные могут делиться между потоками, потому что все они имеют общий общий код address space. Однако вы действительно хотите синхронизировать такой общий доступ (потому что вы не можете знать, без явной синхронизации, когда один поток видит изменения, сделанные другим потоком, читайте о cache coherence). Обычный способ - использовать для этого mutexes.

Чтобы объяснить немного, объявить глобальный семафор с общими глобальными данными:

pthread_mutex_t glob_mtx = PTHREAD_MUTEX_INITIALIZER; 
static struct globaldata_st glob_data; 

Затем, чтобы получить доступ к некоторым данным, например, сделать

int sharednumber; 
pthread_mutex_lock(&glob_mtx); 
sharednumber = glob_data.number; 
pthread_mutex_unlock(&glob_mtx); 

И атомарно обновление, данные, по его приращением:

int sharednumber; 
pthread_mutex_lock(&glob_mtx); 
sharednumber = glob_data.number++; 
pthread_mutex_unlock(&glob_mtx); 

вы так же сериализации обновление или доступ к общей очереди, связанной список, и т.д ....

Не стесняйтесь использовать мьютексы, это quite fast. Всегда Сопряжение pthread_mutex_lock с pthread_mutex_unlock ....

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

С GCC 4.8 на Linux/x86-64 вы можете использовать нить дезинфицирующее с gcc -Wall -fsanitize=thread -g, чтобы облегчить отладку.

Смежные вопросы