C ++使用卡在函数调用中的辅助线程取消pthread
C++ cancelling a pthread using a secondary thread stuck in function call
我在我的 pthreads
之一中设置超时时遇到问题。我在这里简化了我的代码,并将问题隔离为我在线程中 运行ning 的 CNF 算法。
int main(){
pthread_t t1;
pthread_t t2;
pthread_t t3; //Running multiple threads, the others work fine and do not require a timeout.
pthread_create(&t1, nullptr, thread1, &args);
pthread_join(t1, nullptr);
std::cout << "Thread should exit and print this\n"; //This line never prints since from what I've figured to be a lack of cancellation points in the actual function running in the thread.
return 0;
}
void* to(void* args) {
int timeout{120};
int count{0};
while(count < timeout){
sleep(1);
count++;
}
std::cout << "Killing main thread" << std::endl;
pthread_cancel(*(pthread_t *)args);
}
void *thread1 (void *arguments){
//Create the timeout thread within the CNF thread to wait 2 minutes and then exit this whole thread
pthread_t time;
pthread_t cnf = pthread_self();
pthread_create(&time, nullptr, &timeout, &cnf);
//This part runs and prints that the thread has started
std::cout << "CNF running\n";
auto *args = (struct thread_args *) arguments;
int start = args->vertices;
int end = 1;
while (start >= end) {
//This is where the issue lies
cover = find_vertex_cover(args->vertices, start, args->edges_a, args->edges_b);
start--;
}
pthread_cancel(time); //If the algorithm executes in the required time then the timeout is not needed and that thread is cancelled.
std::cout << "CNF END\n";
return nullptr;
}
我尝试注释掉 find_vertex_cover
函数并添加一个 infinite loop
,然后我能够创建一个 timeout
并以这种方式结束线程。该功能实际上按照它应该的方式工作。在我 运行 的条件下,它应该永远 运行 ,因此我需要超时。
//This was a test thread function that I used to validate that implementing the timeout using `pthread_cancel()` this way works. The thread will exit once the timeout is reached.
void *thread1 (void *args) {
pthread_t x1;
pthread_t x2 = pthread_self();
pthread_create(&x1, nullptr, to, &x2);
/*
for (int i = 0;i<100; i++){
sleep(1);
std::cout << i << std::endl;
}
*/
}
使用这个函数,我能够验证我的超时线程方法是否有效。问题是当我实际上 运行 CNF 算法(在引擎盖下使用 Minisat)一次 find_vertex_cover
运行s 时,没有办法结束线程。在我正在实施的情况下,该算法预计会失败,这就是实施超时的原因。
我已经阅读了有关使用 pthread_cancel()
的内容,虽然这不是一个好方法,但这是我实现超时的唯一方法。
如能就此问题提供任何帮助,我们将不胜感激。
I've read up on using pthread_cancel() and while it isn't a great way [..]
没错。 pthread_cancel
应该避免。它 尤其是 不适合在 C++ 中使用,因为它与异常处理不兼容。您应该使用 std::thread
并且对于线程终止,您可以使用条件变量或在设置时终止 "infinite loop" 的原子变量。
除此之外,通过 pthread_cancel
取消取决于两件事:1) 取消状态 2) 取消类型。
默认取消状态为启用。但默认的取消类型是 deferred - 这意味着取消请求将仅在下一个取消点交付。我怀疑 find_vertex_cover
中有任何取消点。因此,您可以通过调用将取消类型设置为 asynchronous
:
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
您希望能够立即取消的线程。
但是,我再次建议完全不要采用 pthread_cancel
方法,而是重写 "cancel" 逻辑,使其不涉及 pthread_cancel
.
我在我的 pthreads
之一中设置超时时遇到问题。我在这里简化了我的代码,并将问题隔离为我在线程中 运行ning 的 CNF 算法。
int main(){
pthread_t t1;
pthread_t t2;
pthread_t t3; //Running multiple threads, the others work fine and do not require a timeout.
pthread_create(&t1, nullptr, thread1, &args);
pthread_join(t1, nullptr);
std::cout << "Thread should exit and print this\n"; //This line never prints since from what I've figured to be a lack of cancellation points in the actual function running in the thread.
return 0;
}
void* to(void* args) {
int timeout{120};
int count{0};
while(count < timeout){
sleep(1);
count++;
}
std::cout << "Killing main thread" << std::endl;
pthread_cancel(*(pthread_t *)args);
}
void *thread1 (void *arguments){
//Create the timeout thread within the CNF thread to wait 2 minutes and then exit this whole thread
pthread_t time;
pthread_t cnf = pthread_self();
pthread_create(&time, nullptr, &timeout, &cnf);
//This part runs and prints that the thread has started
std::cout << "CNF running\n";
auto *args = (struct thread_args *) arguments;
int start = args->vertices;
int end = 1;
while (start >= end) {
//This is where the issue lies
cover = find_vertex_cover(args->vertices, start, args->edges_a, args->edges_b);
start--;
}
pthread_cancel(time); //If the algorithm executes in the required time then the timeout is not needed and that thread is cancelled.
std::cout << "CNF END\n";
return nullptr;
}
我尝试注释掉 find_vertex_cover
函数并添加一个 infinite loop
,然后我能够创建一个 timeout
并以这种方式结束线程。该功能实际上按照它应该的方式工作。在我 运行 的条件下,它应该永远 运行 ,因此我需要超时。
//This was a test thread function that I used to validate that implementing the timeout using `pthread_cancel()` this way works. The thread will exit once the timeout is reached.
void *thread1 (void *args) {
pthread_t x1;
pthread_t x2 = pthread_self();
pthread_create(&x1, nullptr, to, &x2);
/*
for (int i = 0;i<100; i++){
sleep(1);
std::cout << i << std::endl;
}
*/
}
使用这个函数,我能够验证我的超时线程方法是否有效。问题是当我实际上 运行 CNF 算法(在引擎盖下使用 Minisat)一次 find_vertex_cover
运行s 时,没有办法结束线程。在我正在实施的情况下,该算法预计会失败,这就是实施超时的原因。
我已经阅读了有关使用 pthread_cancel()
的内容,虽然这不是一个好方法,但这是我实现超时的唯一方法。
如能就此问题提供任何帮助,我们将不胜感激。
I've read up on using pthread_cancel() and while it isn't a great way [..]
没错。 pthread_cancel
应该避免。它 尤其是 不适合在 C++ 中使用,因为它与异常处理不兼容。您应该使用 std::thread
并且对于线程终止,您可以使用条件变量或在设置时终止 "infinite loop" 的原子变量。
除此之外,通过 pthread_cancel
取消取决于两件事:1) 取消状态 2) 取消类型。
默认取消状态为启用。但默认的取消类型是 deferred - 这意味着取消请求将仅在下一个取消点交付。我怀疑 find_vertex_cover
中有任何取消点。因此,您可以通过调用将取消类型设置为 asynchronous
:
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
您希望能够立即取消的线程。
但是,我再次建议完全不要采用 pthread_cancel
方法,而是重写 "cancel" 逻辑,使其不涉及 pthread_cancel
.