Несколько потоков с блокировками против отдельных потоков? - PullRequest
1 голос
/ 26 сентября 2011

Я разрабатываю программу сокета клиента и сервера. У меня есть файл для передачи на сервер от клиента с использованием UDP, повторяю, я использую UDP ..... Я отправляю через UDP, поэтому скорость отправки слишком высока, чем у получателя, поэтому я создал 3 потока, прослушивающих один и тот же сокет, так что когда один поток выполняет какую-то работу (я имею в виду запись в файл с помощью fwrite) с полученные данные другой поток может получить от клиента.

Мой 1-й вопрос: когда я использую fwrite с несколькими потоками, я должен использовать блокировки, так как указатель файла разделяется между потоками. Я прав в мышлении ???

Мой второй вопрос: «Будет ли какое-либо улучшение производительности, если я буду использовать несколько потоков для записи с использованием блокировок, а не для одного потока, чтобы выполнить работу fwrite без блокировок ... ???» ... Пожалуйста, руководство я ...

Ответы [ 5 ]

2 голосов
/ 26 сентября 2011

Я бы использовал одну нить.Сохраняет осложнения.Вы можете буферизовать данные и использовать асинхронные записи

http://www.gnu.org/s/hello/manual/libc/Asynchronous-Reads_002fWrites.html

2 голосов
/ 26 сентября 2011

Кэшируйте данные перед записью.Пусть запись происходит в другом потоке.

Чтобы сделать это так, как вам нужно, потребуется блокировка сокета.

Q1: да, вам нужно заблокировать его (очень медленно!).Почему бы не использовать отдельный файловый дескриптор в каждом потоке?проблема в основном связана с текущей позицией файла, управляемой этим дескриптором.

Q2: Ни то, ни другое.Если данные требуют упорядочения (да, UDP!), Вы все равно должны их буферизовать.Оперативная память намного быстрее, чем дисковый ввод-вывод.Поток потока для буферизации и обработки данных в этом потоке в отдельном потоке.

1 голос
/ 26 сентября 2011

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

В любом случае, не помещайте запись файла в другой поток.Современные операционные системы в любом случае будут внутренне буферизовать запись на диск - вы начнете блокировать, только если вы записываете данные намного быстрее, чем может выдержать диск, и в этом случае буферизация внутри вашего процесса даст вам не более нескольких секунд.Переключитесь на TCP или используйте соответствующий механизм управления потоком.

1 голос
/ 26 сентября 2011

Аналогично Ответ Эда , я бы предложил использовать асинхронный ввод-вывод и один поток для вашего сервера.Хотя я считаю, что Boost.Asio проще, чем posix AIO.

1 голос
/ 26 сентября 2011

Мой 1-й вопрос: когда я использую fwrite с несколькими потоками, я должен использовать блокировки, так как указатель файла разделяется между потоками

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

Мой второй вопрос: «Будет ли какое-либо улучшение производительности, если я использую несколько потоков для записи с использованием блокировок, а не для одного потока, чтобы выполнить работу fwrite без блокировок… ???»

Я бы использовал две темы. Первый поток ничего не делает, кроме чтения из сокета и сохранения данных в памяти. Второй поток читает данные из памяти и записывает их в файл. Рассматривайте буфер памяти как очередь FIFO и используйте мьютекс для защиты указателей очереди. Вы ничего не получите от третьего потока. Фактически, это, вероятно, повредит производительности и определенно усложнит проблему.

...