gpt4 book ai didi

c - 重新运行已取消的 pthread

转载 作者:行者123 更新时间:2023-11-30 17:25:10 24 4
gpt4 key购买 nike

我的问题是我无法重用已取消的 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;
}
}
}

此示例应创建两个线程 - 一个将在程序开始时创建,并在启动后立即尝试取消第二个线程,第二个线程应在取消后立即重新运行并说“我在这里”。但是,当算法线程取消一次后,它不会再次启动,它会说“正在启动算法”并且什么都不做,不再有“我在这里”消息。您能告诉我如何再次启动已取消(立即停止)的线程吗?

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

此外,有时在 pthread_cancel 上我的程序会崩溃,并显示“必须安装 libgcc_s.so.1 才能使 pthread_cancel 工作”

最佳答案

几点:

首先,这不安全:

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标记为 volatile 。这意味着编译器可以优化 stopAlgorithm 来读取变量一次,并且永远不会重新读取它。其次,您没有确保对它的访问是原子的,也没有通过互斥锁来保护它。要么声明它:

volatile sig_atomic_t thread_available;

(或类似的),或者更好的是,通过互斥锁来保护它。

但是对于从另一个线程触发一个线程的一般情况,您最好使用条件变量(和互斥体),在监听线程中使用 pthread_condwaitpthread_condtimedwait ,以及触发线程中的 pthread_condbroadcast

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

接下来,你关心你的算法被取消后在哪里吗?如果没有,只需 pthread_cancel 即可。如果是这样(无论如何,我认为它要好得多),请定期检查标志(如上所述的原子和 volatile 标志,或受互斥体保护)和 pthread_exit 如果已设置。如果您的算法每秒左右处理大块,那么请检查它。如果它做了很多小事情,请每 1,000 次操作检查一次,这样获取互斥体就不会造成性能损失。

最后,如果您取消一个线程(或者如果它是pthread_exit),那么您再次启动它的方法就是再次调用pthread_create。然后它是一个运行相同代码的新线程。

关于c - 重新运行已取消的 pthread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27105350/

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