У нас есть проблема со временем в цикле C while. в одной части программы цикл while получает информацию от датчика по протоколу SPI и сохраняет ее в базе данных Mysql. Проблема возникает, когда мы проверяем сохраненные данные. Например, в базе хранится 600 данных в секунду, но через несколько секунд количество хранимых данных уменьшается до 400, а через несколько секунд возвращается к 600 в секунду и так далее. Я знаю, что скорость передачи данных с датчика работает на фиксированных часах и не может быть изменена. Но я не знаю, где эта проблема возникает.
вот код цикла while в c:
while(1)
{
tx_buff[0] = 0x08 ;
tx_buff[0] = (tx_buff[0] << 1) | 1;
tx_buff[1] = 0xFF;
tx_buff[2] = 0xFF;
tx_buff[3] = 0xFF;
tx_buff[4] = 0xFF;
tx_buff[5] = 0xFF;
tx_buff[6] = 0xFF;
tx_buff[7] = 0xFF;
tx_buff[8] = 0xFF;
tx_buff[9] = 0xFF;
tinkerboard_set_gpio_state(24, LOW);
tinkerboard_spi_transfer(SPI2, tx_buff, rx_buff,10, mode);
tinkerboard_set_gpio_state(24, HIGH);
X_unsigned = (rx_buff[1]<<16) | (rx_buff[2]<<8)| (rx_buff[3]);
X_unsigned = X_unsigned >> 4;
X_signed = adc24to32(X_unsigned);
Y_unsigned = (rx_buff[4]<<16) | (rx_buff[5]<<8)| (rx_buff[6]);
Y_unsigned = Y_unsigned >> 4;
Y_signed = adc24to32(Y_unsigned);
Z_unsigned = (rx_buff[7]<<16) | (rx_buff[8]<<8)| (rx_buff[9]);
Z_unsigned = Z_unsigned >> 4;
Z_signed = adc24to32(Z_unsigned);
printf(" X=%5.4f Y=%5.4f Z=%5.4f \n",
X_signed*0.0039,Y_signed*0.0039,Z_signed*0.0039);
sprintf(query, "INSERT INTO PO(x,y,z) VALUES(%5.4f,%5.4f,%5.4f)",
X_signed*0.0039,Y_signed*0.0039,Z_signed*0.0039);
//conect to sql
mysql_query(conn, query);
}
Если да, то это не то, на что следует полагаться для ответов RT, поскольку FS в любой момент может «выбрать» реорганизацию, что приведет к значительному отставанию. Как правило, вы должны настроить другой поток для выполнения этой операции и из своего цикла while
отправить его как сообщение в этот другой поток.
да это .@ goodvibration
То же самое касается печати BTW - в идеале у вас должен быть еще один поток только для этого (также известный как поток регистрации).
Я должен попробовать этот путь. сохраненные данные в другом потоке?
Вы настраиваете несколько потоков, которые взаимодействуют друг с другом через очереди сообщений. Здесь вам нужно отправить эти данные в поток, который сохранит их в файле SQL. В тех случаях, когда операция FS занимает больше времени, очередь сообщений этого потока становится более заполненной (с сообщениями, которые еще не обработаны). Затем, как только эта операция будет завершена, очередь постепенно «вернется в нормальное состояние», и в ней будет находиться всего несколько сообщений. Поэтому вы должны убедиться, что используете достаточно большую очередь сообщений, чтобы справляться со случайными задержками.
Некоторые планировщики Unix также штрафуют процессы, которым было предоставлено время выполнения за последние несколько секунд, в пользу тех, которым этого не требовалось. Это может привести к колебаниям процессорного времени.
Наша ОС является дистрибутивом Debian. если проблема оттуда, как мы можем ее решить? Я имею в виду, есть ли способ решить эту проблему вообще? @Jens
Вы можете поиграть со значением nice
для процесса, увеличив приоритет планирования. См. справочную страницу.
Две вещи.
Сначала откройте соединение с сервером MySql и повторно используйте его. Не открывайте новое соединение для каждой вставки: это слишком медленно. И имейте в виду, что объекты подключения MySql не являются потокобезопасными.
Во-вторых, MySql наиболее эффективно обрабатывает массовые операции вставки, если многие из них объединяются в одну транзакцию базы данных. И ваш проект выполняет массовые вставки.
Подходящее количество операций вставки для объединения составляет 100 или около того. Это повышает эффективность сервера MySql, поскольку большая часть работы по вставке выполняется при фиксации транзакции. Если вы не завернете свои вставки в START TRANSACTION;
и COMMIT;
, MySql сделает автоматическую фиксацию. Это означает, что каждая вставка также является транзакцией, и накладные расходы выходят из-под контроля.
Это достаточно легко организовать. При первом открытии соединения установите для переменной обратного отсчета значение 100 и введите START TRANSACTION;
в MySql.
Когда вы делаете каждую вставку, уменьшайте переменную обратного отсчета. Когда он достигнет нуля, сбросьте его и сделайте COMMIT;
, а затем еще START TRANSACTION;
.
Это не превратит ваш проект в проект жесткого реального времени, но очень поможет с накладными расходами MySql.
И рассмотрите возможность запуска MySql на другом хост-компьютере.
and stores it in a mysql database
- это операция дискового ввода-вывода (файловой системы)?