не совсем FIFO - PullRequest
       32

не совсем FIFO

0 голосов
/ 01 октября 2009

Я ломаю голову, но не могу найти решение для этого. Пожалуйста, рассмотрите этот сценарий:

У меня есть писатели, которые хотят записывать в неблокирующую «очередь» на другой компьютер в локальной сети, и у меня есть читатель, который будет считывать данные (режим блокировки, если нет записывающих устройств) и выполнять некоторую работу A, а затем возвращаться после долгий час и возьмите следующие данные.

Итак, сценарий такой:

  • Писатель пишет
  • Писатель пишет
  • Писатель пишет
  • Писатель пишет
  • Писатель пишет
  • Читатель читает и выполняет работу

    В то же время, когда читатель занят:

  • Писатель пишет
  • Писатель пишет
  • Писатель пишет
  • Писатель пишет
  • Писатель пишет
  • и т.д ...

Я думал, что смогу сделать это с демоном tcp в качестве читателя, но это будет означать, что он будет работать одновременно с fork (s), и я хочу, чтобы читатель обрабатывал по одному за раз, потому что он будет выполнять работу, требующую ресурсов процессора .

Я думал о том, чтобы tcp-сервер получал запросы, а затем передавал сигнал в FIFO и получал другого демона, считываемого из FIFO, но у него те же ограничения.

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

ДБ решение будет в порядке, но а) оно не очень быстрое и б) нет блокировки для читателя .. Я бы не хотел реализовывать его с помощью sleep (x), это кажется не очень хорошей техникой программирования .

Какие-нибудь решения?

Ответы [ 3 ]

1 голос
/ 01 октября 2009

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

0 голосов
/ 01 октября 2009

один вариант - иметь сервер (писатель) и клиентский узел. это описывает общий подход:

Сервер создает задания и помещает их в локальную очередь:

// server thread
while(true)
{
     job = generate();
     jobs_queue.push(job); // push job to a local queue on the server
}

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

// server acceptor
while(true)
{
     c = wait_for_connection();
     while(connected(c))
     {
          while(queue.size() >  0)
              c.write(queue.pop()); // send a job to the client

          // block till queue is not empty. can be achieved with sleep or by using a mutex.
     }
}

клиентский узел будет сидеть на tcp-сокете, читать задания и помещать их в локальную очередь (на клиенте). есть поток клиента, который работает так:

// client thread that poll from server
while(true)
{
    job = readNextJob(); // tcp, blocks if there is nothing to read
    queue.push(job);
}

// client thread that spawn jobs from queue
while(true)
{
    job = queue.pop(); // blocks if queue empty
    job.execute();
    job.waitForCompletion();
}
0 голосов
/ 01 октября 2009

Многопоточность выглядит как путь для подражания. Создайте поток, который начинает чтение или запись, и используйте другой поток в другой задаче. Вам нужно будет обеспечить некоторую многопоточную связь между потоками, если вам нужно передать данные от читателя писателю. Вы также можете рассмотреть возможность использования более одного потока для написания, в зависимости от контекста приложения.

С простым C в системе POSIX pthreads - это путь.

...