Спящий рабочий поток на файловом сервере - PullRequest
1 голос
/ 08 июня 2011

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

Я не уверен, как реализовать последнюю строку. Именно так я могу уложить поток в спящий режим и снова его разбудить.

спасибо

Ответы [ 6 ]

0 голосов
/ 12 июня 2011

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

0 голосов
/ 09 июня 2011

Ваши потоки обработки клиента содержат какое-либо состояние для клиента?Если это так, я могу понять, зачем вам нужен один отдельный поток для каждого клиента.Если это так, вы можете использовать очередь «производитель-потребитель» для каждого потока «клиент-обработчик», как это было предложено Cnicutar и другими авторами.Я обычно использую семафор вместе с мьютексом, поскольку такая синхронизация доступна на всех платформах, но condvars OK.Непонятно, как вы идентифицируете клиента при поступлении файлового запроса, поэтому управление потоками клиента может быть неудобным или нет.Когда запрос файла поступает в основной поток, как узнать, в какую очередь его выдвигать?

Rgds, Martin

0 голосов
/ 08 июня 2011

Вам следует изучить проблему производителей-потребителей. В двух словах вы хотите сделать что-то вроде этого:

  • Рабочий поток пытается получить"задание" из очереди
  • Если очередь пуста, поток блокирует (семафор / переменная условия), в противном случае он получает задание и обрабатывает его
  • Основная очередь помещает заданий в очереди и уведомляет рабочих ("эй, есть работа")
  • Уведомленный работник мгновенно просыпается и пытается получить работу из очереди

Хитрость в том, чтобы сделать это по-настоящему элегантно:

  • get должен автоматически блок когда очередь пуста
  • поставить следует автоматически сигнал рабочих, ожидающих его

Как бы вы поступили с тем, что Linux предоставляет в ваше распоряжение?

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

0 голосов
/ 08 июня 2011

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

  • Разрешить возврат методу вашего рабочего потока, когда у него нет работы
  • Когда ваш родительский поток получает запрос, добавьте его в очередь рабочего потока и вызовите метод "Wakeup" в соответствии с:

    private void Wakeup()
    {
        if (!_workerThread.IsBusy)
            _workerThread.RunWorkerAsync();
    }
    

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

0 голосов
/ 08 июня 2011

Вы не "усыпляете нить". Поток будет спать, когда он делает какой-либо системный вызов блокировки.

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

Рабочий поток перейдет в спящий режим, когда он ожидает переменную условия (pthread_cond_wait), и мастер разбудит его, сообщив переменную условия (pthread_cond_signal).

Небольшой поиск должен найти ряд примеров кода на основе pthread для очередей.

0 голосов
/ 08 июня 2011

Использовать переменные условия https://computing.llnl.gov/tutorials/pthreads/#ConVarSignal

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...