Если вы используете разделяемую память, есть ли еще преимущества для процессов перед многопоточностью? - PullRequest
2 голосов
/ 12 января 2011

Я написал приложение для Linux, в котором основной процесс «потребителя» разветвляет группу процессов «чтения» (~ 16), которые считывают данные с диска и передают их «потребителю» для отображения.Данные передаются через сокет, который был создан до разветвления с использованием socketpair.

Я изначально записал его с этой границей процесса по 3 причинам:

  1. Процесс-потребитель имеетограничения в реальном времени, поэтому я хотел избежать выделения памяти у потребителя.Читатели могут свободно распределять память по своему усмотрению или даже писать на другом языке (например, с сборкой мусора), и это не прерывает потребителя, который имеет приоритет FIFO.Кроме того, доступ к диску или другие операции ввода-вывода в процессе чтения не будут прерывать потребителя.Я полагал, что с потоками я не мог получить такие гарантии.

  2. Использование процессов не позволит мне, программисту, делать глупости, такие как использование глобальных переменных и забивать память других процессов.

  3. Я подумал, что отбросить кучу рабочих будет лучшим способом использования нескольких архитектур ЦП, и я решил, что использование процессов вместо потоков, как правило, будет безопаснее.

Не все читатели всегда активны, однако те, кто активен, постоянно отправляют большие объемы данных.В последнее время я думал, что для оптимизации этого, избегая копий памяти, связанных с записью и чтением сокета, было бы неплохо просто прочитать данные непосредственно в буфер общей памяти (shm_open / mmap).Тогда через сокет будет передаваться только индекс в эту разделяемую память, и потребитель будет читать непосредственно из него, прежде чем снова пометить его как доступный.

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

Ответы [ 3 ]

3 голосов
/ 12 января 2011

Ваше предположение, что вы не можете выполнить свои ограничения в реальном времени с потоками, ошибочно. IO или выделение памяти в потоках считывателя не может остановить поток потребителя, если поток потребителя не использует сам malloc (что, конечно, может привести к конфликту блокировки). Я бы порекомендовал прочитать, что POSIX говорит по этому вопросу, если вы не уверены.

Что касается других причин использовать процессы вместо потоков (безопасность, возможность написания читателей на другом языке и т. Д.), Они вполне законны. Пока ваш потребительский процесс обрабатывает буфер совместно используемой памяти как потенциально небезопасные внешние данные, я не думаю, что вы теряете сколько-нибудь значительную степень безопасности, переключаясь с конвейеров на разделяемую память.

0 голосов
/ 25 января 2011

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

Что касается индексной связи между вашей задачей, следует отметить, что затем вы можете использовать для этого область в общей памяти и мьютекс для доступа, поскольку она, вероятно, менее тяжелая, чем связь через сокет. Связь дескриптора файла (сокеты, каналы, файлы и т. Д.) Всегда включает в себя ядро, разделяемую память с блокировками мьютекса или семафоры только в случае конфликта.

При программировании с общей памятью в многопроцессорной среде следует учитывать один момент: избегать ложных зависимостей от переменных. Это происходит, когда два несвязанных объекта совместно используют одну и ту же строку кэша. Когда один из них модифицирован, он «загрязняет» и другой, что означает, что, если другой процессор обращается к другому объекту, он запускает синхронизацию кэша между процессорами. Это может привести к плохому масштабированию. Выравнивая объекты по размеру строки кэша (обычно 64 байта, но может отличаться от архитектуры к архитектуре), этого легко избежать.

0 голосов
/ 12 января 2011

Основной причиной, по которой я столкнулся в процессе замены процессов потоками, была эффективность.Если в ваших процессах используется много кода или неразделенной памяти, которая может быть разделена в многопоточности, вы можете добиться высокой производительности на многопоточных ЦП, таких как ЦП SUN Sparc, имеющих 64 или более потоков на ЦП.В этом случае кэш-память ЦП, особенно для кода, будет намного более эффективной с многопоточным процессом (кэш-память небольшого размера в Sparc).

Если вы видите, что ваше программное обеспечение не работает быстрее при работе на новом оборудованиис большим количеством потоков ЦП, тогда вы должны рассмотреть многопоточность.В противном случае ваши аргументы об избежании этого кажутся мне полезными.

Я еще не сталкивался с этой проблемой на процессорах Intel, но это может произойти в будущем, когда они добавят больше ядер на процессор.

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