我的问题是我无法重复使用已取消的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;
答案 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_condwait
或pthread_condtimedwait
,并{{1}在触发线程中。
接下来,pthread_condbroadcast
线程有什么意义?它所做的只是在0到6秒之间不可预测的时间后取消stopAlgorithm
线程?为什么不从主线程发送algorithm
?
接下来,您是否关注取消算法时的位置?如果没有,只需pthread_cancel
。如果是这样(并且无论如何,我认为它更好),定期检查一个标志(如上所述的原子和易失性,或受互斥锁保护)和pthread_cancel
(如果已设置)。如果你的算法每隔一秒左右做大块,那么检查一下。如果它做了很多微小的事情,请检查(比方说)每1,000次操作,因此使用互斥锁不会造成性能损失。
最后,如果您取消某个帖子(或pthread_exit
s),再次启动它的方法就是再次拨打pthread_exit
。然后它是一个运行相同代码的新线程。