我正在使用GTK和GLib中的线程函数开发一个应用库。我有一个线程(从现在起称为线程A),它是当我点击某个图形窗口中的"ok“按钮时创建的。线程A开始执行一些繁重的任务。另一个名为"cancel“的按钮可用于随时停止和结束线程A。
我的目标是为当我点击"cancel“按钮(线程B)时创建的线程编写一个函数,该函数能够结束线程A。
我使用函数g_thread_create创建线程A。但是,我找不到任何类似于g_thread_cancel的函数来使用线程B停止线程A。这是可能的还是不可能的?
非常感谢您提供的任何类型的信息。
发布于 2019-06-05 04:45:14
您可能希望考虑使用GTask在线程中运行任务,而不是使用手动创建的线程。如果您使用g_task_run_in_thread(),该操作将自动在单独的线程中运行。
GTask与GCancellable集成在一起,因此要取消该操作,您可以在“取消”按钮的回调中调用g_cancellable_cancel()。
正如OznOg所说,您应该将GCancellable视为一种温和(且线程安全的)方式,告诉您的任务应该取消。根据长期运行任务的编写方式,您可以在每个循环迭代中检查一次g_cancellable_is_cancelled(),也可以将g_cancellable_source_new()中的GSource添加到任务中的轮询循环中。
advice about using threads with GLib在这里可能也是相关的。
发布于 2019-06-05 18:21:07
我开发了一个代码,能够从一个线程中取消另一个线程,这两个线程都是从一个主线程创建的。根据我的测试,代码可以正常工作:
#include <pthread.h>
#include <stdio.h>
/* these variables are references to the first and second threads */
pthread_t inc_x_thread, inc_y_thread;
/* this function is run by the first thread */
void *inc_x(void *x_void_ptr)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
/* increment x to 100 */
int *x_ptr = (int *)x_void_ptr;
while(++(*x_ptr) < 100000000);
printf("x increment finished\n");
/* the function must return something - NULL will do */
return NULL;
}
/* this function is run by the second thread */
void *inc_y(void *x_void_ptr)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
/* increment y to 100 */
int *x_ptr = (int *)x_void_ptr;
pthread_cancel(inc_x_thread);
while(++(*x_ptr) < 100);
printf("y increment finished\n");
return NULL;
}
/* this is the main thread */
int main()
{
int x = 0, y = 0;
void *res;
/* show the initial values of x and y */
printf("x: %d, y: %d\n", x, y);
/* create a first thread */
if(pthread_create(&inc_x_thread, NULL, inc_x, &x)) {
fprintf(stderr, "Error creating thread\n");
return 1;
}
/* create a second thread */
if(pthread_create(&inc_y_thread, NULL, inc_y, &y)) {
fprintf(stderr, "Error creating thread\n");
return 1;
}
/* wait for the first thread to finish */
if(pthread_join(inc_x_thread, &res)) {
fprintf(stderr, "Error joining thread\n");
return 2;
}
if (res == PTHREAD_CANCELED)
printf(" thread was canceled\n");
else
printf(" thread wasn't canceled\n");
/* wait for the second thread to finish */
if(pthread_join(inc_y_thread, &res)) {
fprintf(stderr, "Error joining thread\n");
return 2;
}
if (res == PTHREAD_CANCELED)
printf(" thread was canceled\n");
else
printf(" thread wasn't canceled\n");
/* show the results*/
printf("x: %d, y: %d\n", x, y);
return 0;
}可以使用以下命令编译代码:gcc example.c -lpthread
然而,正如OznOg和Philip Withnall所说,这不是取消线程的正确方式。这只是一种在某些特定情况下可能不起作用的快速方法。一种更好、更安全的方法是轻轻地要求线程自行停止。
https://stackoverflow.com/questions/56449966
复制相似问题