Пишу на qt. Цель - быстродействие. Размеры потребляемой памяти не особо важны.
1-й процесс является библиотекой которая подключается к стороннему приложению, получает от него поток данных и размещает их в SharedMemory.
2-й процесс содержит 2 потока, один поток читает данные SharedMemory выбирает нужные и обрабатывает их, второй поток читает SharedMemory и сохраняет данные в БД.
После того как оба потока считали данные, они, видимо, должны как то подать сигнал 1-му процессу, и тогда первый может зачистить данные и записать следующую порцию.
И так по кругу.
1) Оптимальна ли такая архитектура для быстродействия?
2) Как лучше организовать сигнал к 1-му процессу о том что оба потока забрали данные и можно очищать и писать новые? Нужно ли для этого использовать мьютексы/семафоры? Или просто пытаться память захватывать? Мне кажется что оптимальным был бы вариант писать в какой-то буфер статус, аля 0 - данные считаны, можно перезаписывать, 1 - данные забраны первым потоком, 2 - данные забраны вторым потоком. Какими инструментами реализуется такой механизм?
3) Самым медленным звеном в этой цепочке является поток который пишет в БД. Можно ли, при сохранении одного буфера SharedMemory, сделать так чтобы вычисления в первому потоке не ожидали задержки пока данные скинуться в БД?
2) Да, нужно использовать, почитайте что-нибудь про примитивы синхронизации, как работают и как используются в классических задачах.
Очень грубо говоря, второй процесс должен висеть на семафоре, захваченном первым, пока тот пишет данные в SM. После этого уже первый процесс должен висеть на семафоре, захваченном вторым, пока второй поток данные не считает.
3) А зачем вообще ему знать, что там второй поток делает? Считал данные, и сразу начал делать вычисления.
2. Вопрос по схеме с 2 семафорами возник, но покурю мануалы сначала, если не разберусь, напишу ещё.
3. Одному потоку не важно знать что делает второй поток. Просто я вижу там ограничение, что один поток уже всё посчитал и, в принципе, готов принимать новую порцию данных. А т.к. второй поток ещё пишет в БД, то обновление SharedMemory замедляется, по скорости самого медленного потока. И часть времени первый поток простаивать будет.
2. На самом деле я уже тысячу лет не писал ничего многопоточного, и вот так сходу не соображу, как тут быть с тремя потоками на два процесса. Семафора возможно хватит и одного, но лучше бы читать в отдельном, третьем потоке, и внутрипроцессную синхронизацию разруливать отдельно.
3. Если у вас после завершения первого процесса есть возможность некоторое время ещё писать данные в БД, то можно что-то думать, иначе отставание будет всё время накапливаться, и по итогу ни в один буфер не поместится.
samokiller, если уж абстрагироваться от чисто системного уровня (который самый быстрый, но сложный в реализации), и уходить в средства многопоточности в Qt, то все будет проще и незначительно медленнее.
1. Захватываем мьютекс, читаем, отправляем сигнал с указателем на данные, который принимают объекты в других потоках. Это потокобезопасно.
2. Потоки читают данные, и присылают сигналы о том, что данные больше не нужны.
3. Отпускаем мьютекс, его захватывает первый процесс, он пишет, отпускает, и goto 1.
Если надо, данные не удаляем, а куда-нибудь сохраняем, с произвольной логикой для потока с БД. Кстати, писать большими кусками транзакционно может быть сильно быстрее, чем мучить БД каждый такт. .