Многопоточная C помощь в разработке программы - PullRequest
6 голосов
/ 17 марта 2011

У меня нет большого опыта работы с многопоточностью, и я пишу AC-программу, которая, по моему мнению, подходит для работы в двух потоках.Программа будет прослушивать данные через последовательный порт, считывать и обрабатывать новые данные, когда они доступны, и публиковать новейшие обработанные данные в других (не относящихся к делу) модулях через стороннее устройство IPC api (оно вводит в заблуждение IPC)по запросу.

Чтобы получить запрос на публикацию данных через IPC, программа должна вызвать IPC_listenwait (wait_time) ;.Затем, если запрос на публикацию получен во время «прослушивания», вызывается обработчик для публикации новейших данных.

Один из вариантов - сделать это в одном потоке, например:

for(;;) {
  read_serial(inputBuffer);
  process_data(inputBuffer, processedData); //Process and store
  IPC_listenwait(wait_time); //If a request to publish is received during this, 
}                            //then a handler will be invoked and the newest piece of        
                             //processedData will be published to other modules

publishRequestHandler() { //Invoked when a message is received during IPC_listenwait
  IPC_publish(newest(processedData));
}

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

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

readThread() {
    for(;;) { //pseudocode
      select();
      read(inputBuffer);
      process(inputBuffer, processedData);
    }
}

И основной поток просто прослушивает входящие сообщения:

mainThread() {
  IPC_listenwait(forever);
}

publishRequestHandler() { //Invoked when a message is received during IPC_listenwait
  IPC_publish(newest(processedData));
}

Этот дизайн вы бы использовали?Если да, нужно ли использовать семафор при доступе или записи обработанных данных?

Это даст мне хорошую отзывчивость?

Спасибо

1 Ответ

4 голосов
/ 17 марта 2011

Вы в основном на правильном пути.

Единственное, на что вы должны обращать внимание - это параллельный доступ к публикуемым данным, потому что вы не хотите, чтобы один поток перекрывал их, а другой пыталсяпрочитай это.Чтобы предотвратить это, используйте пару буферов и защищенный мьютексом указатель на тот, который считается текущим.Когда у process_data() есть что-то готовое, он должен вывести свои результаты в нетоковый буфер, заблокировать мьютекс указателя, переназначить указатель на буфер, содержащий новые данные, а затем освободить мьютекс.Точно так же издатель должен заблокировать мьютекс указателя, пока он читает текущие данные, что заставит все, что захочет, сжать его, ждать.Это немного сложнее, чем наличие единственного буфера, защищенного мьютексом, но гарантирует, что у вас всегда будет что-то актуальное для публикации во время подготовки новых данных.

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

Отличный первый вопрос, кстати.Имейте upvote.

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