2014-09-29 2 views
0

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

Основной поток:

struct connection *connections[4]; 
// initialize connections 
while (1) 
{ 
    // ... 

    if (...) 
    { 
     pipe(p); 
     connection->control = p[1]; 

     pthread_create(&thread_id, 0, &handler, connections[i]); 
     pthread_detach(thread_id); 

     // ... 
    } 

    // ... 

    if (pipe_data_available[i]) 
    { 
     // do something with connections[i] 
    } 

    // ... 
} 

другой поток:

void *handler(void *arg) 
{ 
    struct connection *connection = arg; 

    // do something with connection 

    write(connection->control, data, data_size); 

    return 0; 
} 

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

У меня есть опасения, что основной поток не может видеть модификации соединений [I] сделано обработчиком (из-за кэша). Может ли это случиться, и если да, то каков наилучший способ убедиться, что основной поток видит изменения?

+1

Этот вид межпоточных комм (т. Е. Проходящий вокруг указателей из некоторого пула) довольно распространен и абсолютно прекрасен, по крайней мере, на оборудовании Intel. Чаще всего это делается с помощью цикла в потоке и блокировки очередей для фактических сообщений, а также для хранения пустых указателей, но то, что вы делаете, кажется мне хорошо (даже если это предотвращает непрерывное создание потоков). –

ответ

0

Нет, не будет проблем с кешем между потоками. Это управляется и не может произойти.

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

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

http://mortoray.com/2010/11/18/cpu-memory-why-do-i-need-a-mutex/

+1

Это совершенно неправильно в общем случае. Когерентность кеша - это определенно проблема. – JeremyP

+0

Да. Эмпирически он отлично работает на аппаратных средствах Intel. –

+0

Я использую трубы, потому что у меня несколько потоков, и я могу опросить(), чтобы увидеть, когда каждый из них заканчивается. – martinkunev

0

На практике это будет работать на большинстве архитектур вы, вероятно, чтобы запустить этот код на. Если вы хотите соответствовать стандартам, прочитайте: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11.

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

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