我希望我的主线程在退出之前等待所有(p)线程完成,这些线程由于不同的原因经常出现和消失,我真的不想跟踪它们的状态 - 我只想知道它们何时结束。
wait()可以用于子进程,当没有子进程时返回ECHILD,但是似乎不适用于(p)线程。
我真的不想麻烦地记录每一个未完成的线程(因为它们来了又走),然后对每个线程调用pthread_join。
有没有一种简单粗暴的方法可以做到这一点?
我希望我的主线程在退出之前等待所有(p)线程完成,这些线程由于不同的原因经常出现和消失,我真的不想跟踪它们的状态 - 我只想知道它们何时结束。
wait()可以用于子进程,当没有子进程时返回ECHILD,但是似乎不适用于(p)线程。
我真的不想麻烦地记录每一个未完成的线程(因为它们来了又走),然后对每个线程调用pthread_join。
有没有一种简单粗暴的方法可以做到这一点?
如果您主线程不需要在所有线程完成后执行任何特定操作,那么您可以让主线程简单地调用pthread_exit()
而不是返回(或调用exit()
)。
如果main()
函数返回,它会隐式地调用(或行为类似于调用)exit()
,这将终止进程。但是,如果main()
函数调用pthread_exit()
而不是返回,那么对exit()
的隐式调用不会发生,并且该进程不会立即结束——它将在所有线程终止时结束。
以下是一个小型示例程序,可让您看到区别。向编译器传递-DUSE_PTHREAD_EXIT
以查看进程等待所有线程完成的情况。在未定义该宏的情况下编译,以查看进程停止线程运行的情况。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
static
void sleep(int ms)
{
struct timespec waittime;
waittime.tv_sec = (ms / 1000);
ms = ms % 1000;
waittime.tv_nsec = ms * 1000 * 1000;
nanosleep( &waittime, NULL);
}
void* threadfunc( void* c)
{
int id = (int) c;
int i = 0;
for (i = 0 ; i < 12; ++i) {
printf( "thread %d, iteration %d\n", id, i);
sleep(10);
}
return 0;
}
int main()
{
int i = 4;
for (; i; --i) {
pthread_t* tcb = malloc( sizeof(*tcb));
pthread_create( tcb, NULL, threadfunc, (void*) i);
}
sleep(40);
#ifdef USE_PTHREAD_EXIT
pthread_exit(0);
#endif
return 0;
}
正确的做法是跟踪所有pthread_id,但您要求一种快速而简单的方法,因此在这里提供一个基本方案:
.
volatile int running_threads = 0;
pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER;
void * threadStart()
{
// do the thread work
pthread_mutex_lock(&running_mutex);
running_threads--;
pthread_mutex_unlock(&running_mutex);
}
int main()
{
for (i = 0; i < num_threads;i++)
{
pthread_mutex_lock(&running_mutex);
running_threads++;
pthread_mutex_unlock(&running_mutex);
// launch thread
}
while (running_threads > 0)
{
sleep(1);
}
}
pthread_t
的标识符,并使用 pthread_join
加入它们。 - R.. GitHub STOP HELPING ICEint main() {
pthread_mutex_lock(&mutex);
void *data;
for(threadId in threadIdList) {
pthread_mutex_unlock(&mutex);
pthread_join(threadId, &data);
pthread_mutex_lock(&mutex);
}
printf("All threads completed.\n");
}
// called by any thread to create another
void CreateThread()
{
pthread_t id;
pthread_mutex_lock(&mutex);
pthread_create(&id, NULL, ThreadInit, &id); // pass the id so the thread can use it with to remove itself
threadIdList.add(id);
pthread_mutex_unlock(&mutex);
}
// called by each thread before it dies
void RemoveThread(pthread_t& id)
{
pthread_mutex_lock(&mutex);
threadIdList.remove(id);
pthread_mutex_unlock(&mutex);
}
#define NUM_THREADS 5
unsigned int thread_count;
void *threadfunc(void *arg) {
printf("Thread %p running\n",arg);
sleep(3);
printf("Thread %p exiting\n",arg);
__sync_fetch_and_sub(&thread_count,1);
return 0L;
}
int main() {
int i;
pthread_t thread[NUM_THREADS];
thread_count=NUM_THREADS;
for (i=0;i<NUM_THREADS;i++) {
pthread_create(&thread[i],0L,threadfunc,&thread[i]);
}
do {
__sync_synchronize();
} while (thread_count);
printf("All threads done\n");
}
thread_count=NUM_THREADS;
for (i=1;i<NUM_THREADS;i++) {
pthread_create(&thread[i],0L,threadfunc,&thread[i]);
}
threadfunc(&thread[0]);
do {
__sync_synchronize();
} while (thread_count);
printf("All threads done\n");
}
pthread_exit()
,那么main()
结尾处的return
语句将不会被执行。线程已经退出,但是没有执行拆除进程的任何机制。操作系统将在进程中的所有线程退出后(或者另一个线程可以调用类似于exit()
的函数来终止进程)执行此操作。 - Michael Burrtcb
会导致内存泄漏吗? - razzexit()
(或让main()
返回)和调用pthread_exit()
之间的区别。它并不意味着展示线程资源完整正确的处理方式。 - Michael Burrpthread_exit()
会自动释放线程。 - razz