重新运行取消了pthread

时间:2014-11-24 12:54:23

标签: c multithreading pthreads embedded-linux

我的问题是我无法重复使用已取消的pthread。示例代码:

#include <pthread.h>

pthread_t alg;
pthread_t stop_alg;
int thread_available;

void *stopAlgorithm() {
    while (1) {
        sleep(6);
        if (thread_available == 1) {
            pthread_cancel(alg);
            printf("Now it's dead!\n");
            thread_available = 0;
        }
    }
}
void *algorithm() {
    while (1) {
        printf("I'm here\n");
    }
}

int main() {
    thread_available = 0;
    pthread_create(&stop_alg, NULL, stopAlgorithm, 0);
    while (1) {
        sleep(1);
        if (thread_available == 0) {
            sleep(2);
            printf("Starting algorithm\n");
            pthread_create(&alg, NULL, algorithm, 0);
            thread_available = 1;
        }
    }
}

这个样本应该创建两个线程 - 一个将在程序开始时创建,并且会在它启动后立即尝试取消第二个,第二个应该在它被取消后立即重新运行并说“&#34; m”这里&#34 ;.但是一旦算法线程没有再次启动就被取消,它会说&#34;启动算法&#34;并没有做任何事情,没有&#34;我在这里&#34;消息了。你能告诉我再次开始取消(立即停止)线程的方法吗?

UPD:所以,多亏了你的帮助,我明白了问题所在。当我重新运行算法线程时,它会抛出错误11:&#34;系统缺少创建另一个线程所需的资源,或者系统强加的进程PTHREAD_THREADS_MAX中线程总数限制将被超出。 #34 ;.实际上我有5个线程,但只有一个被取消,其他被pthread_exit停止。因此,在算法停止并且程序进入待机模式后,我检查了pthread_join所有线程的状态 - 所有线程显示0(取消显示PTHREAD_CANCELED),据我所知,这意味着所有线程已停止成功。但是还有一次尝试运行算法会再次抛出错误11。所以我检查了内存使用情况。在算法之前的待机模式 - 10428,在算法期间,当所有线程使用时 - 2026m,在算法停止后的待机模式 - 2019m。因此,即使线程停止,它们仍然使用内存,pthread_detach对此没有帮助。线程后还有其他方法可以清理吗?

此外,有时在pthread_cancel上我的程序崩溃了&#34;必须安装libgcc_s.so.1才能让pthread_cancel工作&#34;

1 个答案:

答案 0 :(得分:0)

有几点:

首先,这不安全:

int thread_available;

void *stopAlgorithm() {
    while (1) {
        sleep(6);
        if (thread_available == 1) {
            pthread_cancel(alg);
            printf("Now it's dead!\n");
            thread_available = 0;
        }
    }
}

至少原因并不安全。首先,您没有将thread_available标记为易失性。这意味着编译器可以优化stopAlgorithm一次读取变量,并且永远不会重读它。其次,您还没有确保对它的访问是原子的,还是由互斥锁保护它。要么宣布它:

volatile sig_atomic_t thread_available;

(或类似),或更好,用互斥锁保护它。

但是对于从另一个线程触发一个线程的一般情况,您最好使用条件变量(和互斥锁),在侦听线程中使用pthread_condwaitpthread_condtimedwait,并{{1}在触发线程中。

接下来,pthread_condbroadcast线程有什么意义?它所做的只是在0到6秒之间不可预测的时间后取消stopAlgorithm线程?为什么不从主线程发送algorithm

接下来,您是否关注取消算法时的位置?如果没有,只需pthread_cancel。如果是这样(并且无论如何,我认为它更好),定期检查一个标志(如上所述的原子和易失性,或受互斥锁保护)和pthread_cancel(如果已设置)。如果你的算法每隔一秒左右做大块,那么检查一下。如果它做了很多微小的事情,请检查(比方说)每1,000次操作,因此使用互斥锁不会造成性能损失。

最后,如果您取消某个帖子(或pthread_exit s),再次启动它的方法就是再次拨打pthread_exit。然后它是一个运行相同代码的新线程。