Pro*C вызов процедуры зависает бесконечно
У меня есть многопоточная программа Pro*C, которая вызывает анонимные хранимые процедуры в каждом потоке в отдельных соединениях и контекстах времени выполнения.
Мои анонимные вызовы процедур требуют разных временных рамок для возврата из процедуры, а иногда даже зависают на неопределенный срок. Моя процедура Oracle занимает всего 0,05 секунды для возврата, как это показано в журналах AWR, но неожиданно для вызова Pro*C требуется 5 секунд для возврата из процедуры.
Какая обработка выполняется между вызовом процедуры Pro*C и фактическим выполнением процедуры Oracle? Есть ли какие-либо блокировки или другие проблемы с блокировкой?
2 ответа
Вы можете попробовать трассировку Oracle (DBMS_MONITOR) и посмотреть, какое последнее действие выполняется в файле трассировки. Единственное, о чем я могу подумать, это может правильно учитывать время, если процедура возвращает большое значение (BLOB, CLOB, XML), для которого требуется время, чтобы вернуться к клиенту по сети (или когда клиент включается размер полученных данных).
Если он зависает бесконечно, то да, есть некоторый тип блокировки (или опрос и т. Д.... что-то происходит в функции, заставляя ее не возвращаться).
Из вашего другого вопроса, который вы опубликовали по этому вопросу, если вы хотите просто убить конкретную цепочку, которая зависла, то вы можете посмотреть на настройку идентификаторов нитей как структуры, в которой есть флаг "закончен".
#include <pthread.h>
#include <signal.h>
struct thread_id
{
pthread_t thread;
sig_atomic_t thread_flag;
};
void init_thread_id(struct thread_id* id)
{
id->thread_flag = 0;
}
thread_id threads[NUMBER_OF_THREADS];
void* thread_function(void* arg)
{
thread_id* my_id = (thread_id*)arg;
//do something in your thread
//when you finish, set the flag for that thread
my_id->thread_flag = 1;
}
Теперь, когда вы установите будильник, просто прокрутите массив thread_id
и посмотреть, какие из них закончены. Те, которые закончились, вы можете позвонить pthread_join
в противном случае вы можете отправить сигнал в поток, используя pthread_kill
или же pthread_cancel
чтобы остановить поток.