gpt4 book ai didi

c - PTHREAD_CANCEL_ASYNCHRONOUS 取消整个过程

转载 作者:太空狗 更新时间:2023-10-29 15:18:00 33 4
gpt4 key购买 nike

在 C 程序中,我使用 PTHREAD_CANCEL_ASYNCHRONOUS 立即取消线程,一旦从父线程触发 pthread_cancel。但它导致整个过程因 Segmentation Fault 而崩溃。子线程的工作是从数据库服务器获取一些数据。而我的逻辑是,如果它在 10 秒内没有获取数据,则该线程应该从父线程中被杀死。

我只想杀死子线程,而不是整个进程。

struct str_thrd_data
{
SQLHANDLE hstmt;
int rc;
bool thrd_completed_flag;
};


void * str_in_thread_call(void *in_str_arg)
{
int thrd_rc;
struct str_thrd_data *str_arg;
str_arg = in_str_arg;

thrd_rc = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (thrd_rc != 0)
handle_error_en(thrd_rc, "pthread_setcancelstate");

thrd_rc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (thrd_rc != 0)
handle_error_en(thrd_rc, "pthread_setcancelstate");

thrd_rc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
if (thrd_rc != 0)
handle_error_en(thrd_rc, "pthread_setcanceltype");
// Code to call SQL Dynamic Query from a Database Server. This takes time more than 10 seconds.
thrd_rc = SQLExecute(hstmt);
printf("\n*********************Normal Thread termination withing timelimit %d\n",str_arg->rc);
str_arg->thrd_completed_flag = true;

}

int main()
{
printf("\nPJH: New THread created.\n");
pthread_attr_t tattr;
pthread_t th;
size_t mysize = 1;

struct str_thrd_data atd;

atd.hstmt = hstmt;
atd.rc= rc;
atd.thrd_completed_flag = false;

thrd_rc = pthread_attr_init(&tattr);
thrd_rc = pthread_attr_setstacksize(&tattr, mysize);
thrd_rc = pthread_create(&th, &tattr, &str_in_thread_call, &atd);
if (thrd_rc != 0)
handle_error_en(thrd_rc, "pthread_create");

// While Loop tp count till 10 seconds.
while(timeout !=0)
{
printf("%d Value of rc=%d\n",timeout, atd.rc);
if(atd.rc != 999) break;
timeout--;
usleep(10000);
}
rc = atd.rc;
//Condition to check if thread is completed or not yet.
if(atd.thrd_completed_flag == false)
{
//Thread not comepleted within time, so Kill it now.
printf("PJH ------- 10 Seconds Over\n");
thrd_rc = pthread_cancel(th);
printf("PJH ------- Thread Cancelled Immediately \n");
if (thrd_rc != 0)
{
handle_error_en(thrd_rc, "pthread_cancel");
}
printf("\nPJH &&&&&&&& Thread Cancelled Manually\n");
}
thrd_rc = pthread_join(th,NULL);
// some other job .....
}

gdb process_name corefile 显示以下回溯:- 主要是所有 SQL 库函数。

#0  0xffffe410 in __kernel_vsyscall ()
#1 0x0059fe30 in raise () from /lib/libc.so.6
#2 0x005a1741 in abort () from /lib/libc.so.6
#3 0xdef3f5d7 in ?? () from /usr/lib/libstdc++.so.5
#4 0xdef3f624 in std::terminate() () from /usr/lib/libstdc++.so.5
#5 0xdef3f44c in __gxx_personality_v0 () from /usr/lib/libstdc++.so.5
#6 0x007e1917 in ?? () from /lib/libgcc_s.so.1
#7 0x007e1c70 in _Unwind_ForcedUnwind () from /lib/libgcc_s.so.1
#8 0x007cda46 in _Unwind_ForcedUnwind () from /lib/libpthread.so.0
#9 0x007cb471 in __pthread_unwind () from /lib/libpthread.so.0
#10 0x007c347a in sigcancel_handler () from /lib/libpthread.so.0
#11 <signal handler called>
#12 0xffffe410 in __kernel_vsyscall ()
#13 0x0064decb in semop () from /lib/libc.so.6
#14 0xe0245901 in sqloSSemP () from /opt/IBM/db2/V9.1/lib32/libdb2.so.1
#15 0xe01e7f3c in sqlccipcrecv(sqlcc_comhandle*, sqlcc_cond*) () from /opt/IBM/db2/V9.1/lib32/libdb2.so.1
#16 0xe03fe135 in sqlccrecv () from /opt/IBM/db2/V9.1/lib32/libdb2.so.1
#17 0xe02a0307 in sqljcReceive(sqljCmnMgr*) () from /opt/IBM/db2/V9.1/lib32/libdb2.so.1
#18 0xe02d0ba3 in sqljrReceive(sqljrDrdaArCb*, db2UCinterface*) () from /opt/IBM/db2/V9.1/lib32/libdb2.so.1
#19 0xe02c510d in sqljrDrdaArExecute(db2UCinterface*, UCstpInfo*) () from /opt/IBM/db2/V9.1/lib32/libdb2.so.1
#20 0xe01392bc in CLI_sqlCallProcedure(CLI_STATEMENTINFO*, CLI_ERRORHEADERINFO*) () from /opt/IBM/db2/V9.1/lib32/libdb2.so.1
#21 0xe00589c7 in SQLExecute2(CLI_STATEMENTINFO*, CLI_ERRORHEADERINFO*) () from /opt/IBM/db2/V9.1/lib32/libdb2.so.1
#22 0xe0050fc9 in SQLExecute () from /opt/IBM/db2/V9.1/lib32/libdb2.so.1
#23 0x080a81f7 in apcd_in_thread_call (in_apcd_arg=0xbc8e8f34) at dcs_db2_execute.c:357
#24 0x007c4912 in start_thread () from /lib/libpthread.so.0
#25 0x0064c60e in clone () from /lib/libc.so.6

最佳答案

异步线程取消只能安全地用于执行一组非常有限的操作的线程 — 官方规则冗长且令人困惑,但实际上受异步取消影响的线程只能执行纯计算.它们不能执行 I/O,不能分配内存,不能获取任何类型的锁,而且它们不能调用任何可能执行任何操作的库函数 将异步取消应用于与数据库对话的线程是不安全的。

延迟取消的限制较少,但仍然非常挑剔。如果您的数据库库没有编码以应对调用线程可能在操作中途被取消的可能性——而且它可能不是——那么您也不能安全地使用延迟取消。

您需要找到一些其他机制来中止运行时间过长的查询。

编辑:因为这是 DB2 和名称容易混淆的“CLI”API,请尝试使用 SqlSetStmtAttr在准备好的语句上设置 SQL_ATTR_QUERY_TIMEOUT 参数。 This is the full list of parameters that can be set this way , 和 here is some more discussion of query timeouts .

编辑之子: 据一位从事数据库工作比我多得多的 friend 说,很可能有一种服务器端机制可以取消缓慢的查询,而不管其来源如何。如果 DB2 中存在这种情况,那么它可能比在客户端的所有查询上手动设置超时更方便,特别是因为它可能能够记录慢速查询,以便您知道它们是哪些查询并可以优化它们。

关于c - PTHREAD_CANCEL_ASYNCHRONOUS 取消整个过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16280418/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com