#c #sqlite #pthreads #popen
Вопрос:
Я использую рабочую систему linux, а моя версия sqlite3-3.9.2(2015-11-02)
Моя программа будет писать базу данных sql нерегулярно, и мы будем выполнять команду popen каждые 1 минуту для проверки сети
Обычно моя программа работает, но иногда (примерно 1 раз/1~3 дня) возникает ошибка ввода-вывода диска, и я не знаю, почему…
Журнал выглядит следующим образом
result_buf64 bytes from 8.8.8.8: seq=2 ttl=112 time=10.698 ms
result_buf
result_buf--- 8.8.8.8 ping statistics ---
result_buf3 packets transmitted, 3 packets received, 0% packet loss
------Have External Network Capability-------
SQL error: disk I/O error
Retry SQL error: disk I/O error
Retry SQL error code: 10
Retry SQL error msg: disk I/O error
Error Cause: update config set VALUE=0 where ID=31;
Retry SQL error code detail: 3850
Я использую sqlite3_open для открытия БД,и мой код
int CtrlDB::SqCMD(const char *sql, int retry)
{
//cout << "SQL:[" << sql << "]" << endl;
try {
/* Execute SQL statement */
for (int i = 0 ; i < retry ; i ) {
char *zErrMsg = NULL;
const char *ErrMsg = NULL;
int rc = sqlite3_exec(db, sql, 0, 0, amp;zErrMsg);
int err = sqlite3_errcode(db);
ErrMsg = sqlite3_errmsg(db);
int detailerr = sqlite3_extended_errcode(db);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %sn", zErrMsg);
DC_ERROR_NL("Retry SQL error: %s", zErrMsg);
DC_ERROR_NL("Retry SQL error code: %d", err);
DC_ERROR_NL("Retry SQL error msg: %s", ErrMsg);
DC_ERROR_NL("Error Cause: %s", sql);
DC_ERROR_NL("Retry SQL error code detail: %d", detailerr);
if (CharArrayCheck(zErrMsg, "file is encrypted or is not a database") == 1) {
cout << "bill10" << endl;
RecoverForCrashDB();
}
if(zErrMsg)
sqlite3_free(zErrMsg);
} else {
//fprintf(stdout, "Operation done successfullyn");
return 0;
}
sleep(1);
}
}
catch (...) {
cout << "sql error" << endl;
}
CloseDB();
return 1;
}
Но я открываю только 1 базу данных за раз, но я сомневаюсь, что программа выполняет popen в одно и то же время другим потоком.
Я использую popen для выполнения ping-c 3 8.8.8.8 и использую fget для получения buff, будут ли эти команды конфликтовать с записью sql? Или как решить эту проблему(ошибка ввода-вывода диска)?
char result_buf[100] = { 0 };
char result_buf2[100] = { 0 };
char cmd[] = "ping -c 3 8.8.8.8";
FILE *fp;
if ((fp = popen(cmd, "r")) == NULL)
{
cout << "command error6" << endl;
}
else {
while (fgets(result_buf, sizeof(result_buf), fp) != NULL)
{
cout << "result_buf" << result_buf << endl;
if (strstr(result_buf, "packet loss") != NULL) {
if (strstr(result_buf, " 100% packet loss") == NULL) {
cout << "------Have External Network Capability-------" << endl;
break;
}
else {
cout << "------No External Network Capability-------" << endl;
}
}
}
pclose(fp);
Спасибо за чтение и помощь
Комментарии:
1. Шаг 1: обновление до современной версии sqlite (легко сделать, так как вы используете c )