2013-05-19 5 views
1

Мне нужно создать много очередей FIFO в программе, которая используется для связи между потоками в одном процессе.пишите указатели на трубку, есть ли какие-либо строгие проблемы с псевдонимом или какими-то типами?

Я думаю, что для этой цели я могу использовать pipe(), потому что таким образом я могу использовать select или poll в потоке, который извлекает узлы из очереди.

 int* fd_pipe = (int*)malloc(2*sizeof(int)); 
     pipe(fd_pipe); 

теперь проблема заключается в том, чтобы поместить указатель в очередь , поскольку каждый узел является strucutre, я хочу, чтобы поместить указатель в очередь, что-то вроде

ЬурейеГо { STRUCT Packet * ПКТА; struct Info * info; int seq; } Узел;

on threads which put node into the queue: 

    Node* node = (Node*)malloc(sizeof(Node)); 
    Node->info = ...; 
    Node->seq = ...; 
    Node->pkt = ...; 
    write(fd_pipe[1], node, sizeof(node)); 

    on threads which read node from the queue: 

    char buf[1000]; 
    read(fd_pipe[0], buf, sizeof(node)) 
    Node* mynode = (Node*)buf; 

тогда mynode - это то, что я хочу.

Есть ли что-то не так в моей программе? особенно строгие проблемы с псевдонимом или каламбурой? спасибо!

+0

Вам не нужно указывать возвращаемое значение 'malloc' в программе на языке C. –

+0

Я обновил свой код, вы имеете в виду листинг 'Node * node = (Node *) malloc (sizeof (Node));' не нужно? есть ли другие проблемы в моем исходном коде? – misteryes

+0

'char buf [1000];' определенно неправильно. Это не нарушение наложения, а нарушение выравнивания. Вместо этого вы должны использовать 'Node buf;' –

ответ

2

У вас нет проблем с псевдонимом. Здесь единственная проблема, которую я вижу, - read(fd_pipe[0], buf, sizeof(node)), это должно быть read(fd_pipe[0], buf, sizeof(Node *)).

Я не уверен, почему вы используете буфер обугленного здесь, я предпочитаю

Node *node; 
if (read(fd_pipe[0], &node, sizeof(node)) <= 0) { 
    // error, deal with it 
} 

Это проще и понятнее.

Теперь ваш код будет работать только так, как если бы вы использовали блокирующий ввод-вывод, который является значением по умолчанию. Кроме того, технически вы должны обрабатывать короткие чтения/записи, но запись/чтение на трубе является атомарным, если размер чтения/записи меньше, чем PIPE_BUF (который всегда намного больше, чем указатель)

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

Труба - необычный способ связи между потоками. Обычно люди используют очереди в очереди для обмена данными между потоками. Одним из примеров является http://www.boost.org/doc/libs/1_53_0/doc/html/boost/lockfree/queue.html

+0

Я использую 'C' не' C++', и я хочу использовать select/poll для частого опроса очереди, очередь в памяти кажется не адаптированной к этому сценарию? – misteryes

+0

Я не понимаю ту серую область, о которой вы упомянули, где она? – misteryes

+0

Мне нужно использовать select/poll на fd_pipe [0], зачем нужно блокировать ввод-вывод? что такое короткое чтение/запись. и из этой ссылки http://stackoverflow.com/questions/1712616/multithreading-read-from-write-to-a-pipe, мне кажется, что 'read/write' не является атомарным и блокируется с помощью мьютекса? – misteryes