如何从另一个线程(Glib 线程)取消一个线程



我正在使用GTK和GLib中的线程函数开发一个应用程序库。我有一个线程(从现在开始将称为线程 A(,当我在某个图形窗口中点击"确定"按钮时创建。线程 A 开始执行一些繁重的任务。另一个名为"取消"的按钮可用于随时停止和完成线程 A。

我的目标是为点击"取消"按钮(线程 B(时创建的线程编写一个函数,该函数能够结束线程 A。

我使用函数创建线程 A g_thread_create .但是,我找不到任何类似于使用线程 B 停止线程 A 的g_thread_cancel函数。这是可能的还是不能做到的?

非常感谢您提供任何类型的信息。

您可能需要

考虑使用 GTask 在线程中运行任务,而不是使用手动创建的线程。如果使用 g_task_run_in_thread() ,该操作将自动在单独的线程中运行。

GTaskGCancellable集成,因此要取消操作,您需要从"取消"按钮在回调中调用g_cancellable_cancel()

正如 OznOg 所说,您应该将GCancellable视为一种温和(且线程安全(告诉您的任务应该取消的方式。根据长时间运行的任务的编写方式,您可以在每个循环迭代中检查一次g_cancellable_is_cancelled(),也可以将g_cancellable_source_new()中的GSource添加到任务中的轮询循环中。

关于将线程与 GLib 一起使用的建议可能在这里也相关。

我开发了一个代码,能够取消另一个线程的线程,这两个线程都是从主线程创建的。根据我的测试,代码可以正常工作:

#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 finishedn");
    /* 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 finishedn");
    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: %dn", x, y);
    /* create a first thread */
    if(pthread_create(&inc_x_thread, NULL, inc_x, &x)) {
        fprintf(stderr, "Error creating threadn");
        return 1;
    }
    /* create a second thread */
    if(pthread_create(&inc_y_thread, NULL, inc_y, &y)) {
        fprintf(stderr, "Error creating threadn");
        return 1;
    }
    /* wait for the first thread to finish */
    if(pthread_join(inc_x_thread, &res)) {
        fprintf(stderr, "Error joining threadn");
        return 2;
    }
           if (res == PTHREAD_CANCELED)
               printf(" thread was canceledn");
           else
               printf(" thread wasn't canceledn");
    /* wait for the second thread to finish */
    if(pthread_join(inc_y_thread, &res)) {
        fprintf(stderr, "Error joining threadn");
        return 2;
    }
           if (res == PTHREAD_CANCELED)
               printf(" thread was canceledn");
           else
               printf(" thread wasn't canceledn");
    /* show the results*/
    printf("x: %d, y: %dn", x, y);
    return 0;
}

您可以使用以下命令编译代码: gcc example.c -lpthread

然而,正如OznOg和Philip Withnall所说,这不是取消线程的正确方法。这只是一种快速的方法,在某些特定情况下可能不起作用。更好、更安全的方法是轻轻地让线程自行停止。

最新更新