我正在用C编写一个Unix应用程序,它使用多个控制线程。 我有一个主要函数的问题终止在它产生的线程有改变完成他们的工作之前。 我如何防止这种情况发生。 我怀疑我需要使用pthread_join原语,但我不知道如何。 谢谢!
是的,你可以使用pthread_join()(参见其他方法)。 但让我解释一下pthread模型,并向您展示另一个选项。
在Unix中,当主线程从main返回时,当任何线程调用exit()或最后一个线程调用pthread_exit()时,进程退出。 根据最后一个选项,您可以简单地让主线程调用pthread_exit(),只要至少有一个线程正在运行,进程将保持活动状态。
是这样做的一个是使用pthread_join
函数:这是假设你的线程处于“可连接”状态。
pthread_create
:在这个函数返回控制之后,你的线程将执行你的线程函数。
在pthread_create
之后,使用从pthread_create到pthread__join
的tid 。
如果你的线程是分离的,你必须使用其他一些技术,例如共享变量,等待信号,共享队列等。
伟大的参考资料可在这里 。
有几种不同的方法可以做到这一点,但最简单的方法是在从main()
返回之前调用pthread_exit()
main()
。
请注意,即使您要等待的线程不可连接,此技术也能正常工作。
你可能想看看这个网页: http : //publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/apis/users_25.htm
rc = pthread_create(&thread, NULL, threadfunc, NULL); checkResults("pthread_create()\n", rc); printf("Wait for the thread to exit\n"); rc = pthread_join(thread, &status);
检查我为我的一个库编写的这个简单的C代码
/* * Copyright (c) 2011 Dino Ciuffetti <dino@tuxweb.it>, TuxWeb Srl, NuvolaBase Ltd * * This file is part of liborient. * * Liborient is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Liborient is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Liborient. If not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> //pthread_rwlock_t ptr_thr_lock = PTHREAD_RWLOCK_INITIALIZER; typedef struct { int t; } thread_arguments; void *thread_stuff(void *args) { thread_arguments *t_args; int tid; t_args = (thread_arguments *)args; //pthread_rwlock_rdlock(&ptr_thr_lock); tid = t_args->t; //pthread_rwlock_unlock(&ptr_thr_lock); /*while (1) { sleep (1);*/ printf("Thread #%i!\n", tid); /*}*/ t_args = NULL; pthread_exit(NULL); return NULL; } int wait_threads(pthread_t threads[], thread_arguments *t_args[], int nthreads) { int t; int rc; // Waiting for threads termination for(t=0; t<nthreads; t++) { rc = pthread_join(threads[t], NULL); free(t_args[t]); if (rc != 0) { printf("Error waiting for termination of thread %i: %i\n", t, rc); return 1; break; } } return 0; } int spawn_threads(pthread_t threads[], thread_arguments *t_args[], int nthreads) { int t; int rc; // Spawning threads for(t=0; t<nthreads; t++) { t_args[t] = (thread_arguments *) malloc(sizeof(thread_arguments)); //pthread_rwlock_wrlock(&ptr_thr_lock); t_args[t]->t = t; //pthread_rwlock_unlock(&ptr_thr_lock); printf("Spawning thread: %i\n", t); rc = pthread_create(&threads[t], NULL, (void *)thread_stuff, (void *)t_args[t]); if (rc != 0) { printf("Error spawning thread %i: %i\n", t, rc); wait_threads(threads, t_args, rc+1); return t+1; break; } } return 0; } int main() { pthread_t threads[20]; thread_arguments *t_args[20]; int rc; rc = spawn_threads(threads, t_args, 20); if (rc > 0) { printf("Failed spawning thread number %i\n", rc-1); return 1; } rc = wait_threads(threads, t_args, 20); return 0; }