Я разрабатываю приложение, которое использует API ODB C напрямую, используя драйвер Oracel DB. Все работало нормально, пока я работал однопоточным. Но когда я использую несколько потоков, то почти каждая функция SQL ... завершает процесс. Все, что я обнаружил, похоже, что я все делаю правильно, например, сначала я устанавливаю sh среду, а после этого все потоки просто используют эту среду для создания своего собственного соединения. Вызов SQLAllo c для получения дескриптора соединения все еще работает, но вызов SQLDriverConnectW приводит к ошибке сегментации.
Затем я создал очень простую тестовую программу и получил тот же результат (я перестал обрабатывать код возврата для коротко):
SQLHANDLE environmentHandle = SQL_NULL_HENV;
void testConnect() {
SQLHANDLE connectionHandle = SQL_NULL_HDBC;
SQLAllocHandle(SQL_HANDLE_DBC, environmentHandle, &connectionHandle);
SQLSetConnectAttrW(connectionHandle, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS);
// ...
SQLDriverConnectW(connectionHandle, NULL, szConnectionString, cbConnectionString, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
// ...
}
void runMain() {
SQLRETURN rc;
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &environmentHandle);
// switch to ODBC 3.0
SQLSetEnvAttr(environmentHandle, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
// This works:
// testConnect();
// This works NOT!
std::thread threadObj(testConnect);
threadObj.join();
// ...
}
int main() {
try {
runMain();
}
catch(...) {
std::cout << "error\n";
}
return 0;
}
Если я запускаю эту программу, она вызывает сбой при вызове SQLSetConnectAttrW. Затем я понял, что он взломает sh уже тогда, когда я установлю sh среду, если runMain не вызывается в основном потоке. Если я изменю основную функцию на эту, тогда я получу ошибку, уже вызвав SQLSetEnvAttr.
int main() {
try {
std::thread threadObj(runMain);
threadObj.join();
}
catch(...) {
std::cout << "error\n";
}
return 0;
}
Я не могу себе представить, есть ли ошибка в библиотеке драйверов oracle db. Но я также не могу найти ошибку в моем коде. Кто-нибудь сталкивался с этой проблемой раньше? Может кто-нибудь помочь?
Спасибо!
С уважением, Свен