我必须编写一个多线程程序(比如2个线程),其中每个线程执行不同的任务。此外,一旦启动,这些线程必须在后台无限地运行。这就是我所做的。如果这个方法是好的,如果你看到了一些问题,谁能给我一些反馈吗?此外,我还想知道如何在用Ctrl+C终止执行(比如)之后,以系统的方式关闭线程。
主函数创建两个线程,并让它们无限地运行,如下所示。
这是骨架:
void *func1();
void *func2();
int main(int argc, char *argv[])
{
pthread_t th1,th2;
pthread_create(&th1, NULL, func1, NULL);
pthread_create(&th2, NULL, func2, NULL);
fflush (stdout);
for(;;){
}
exit(0); //never reached
}
void *func1()
{
while(1){
//do something
}
}
void *func2()
{
while(1){
//do something
}
} 谢谢。
编辑的代码使用来自答案的输入:是正确退出线程的吗?
#include <stdlib.h> /* exit() */
#include <stdio.h> /* standard in and output*/
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <signal.h>
#include <semaphore.h>
sem_t end;
void *func1();
void *func2();
void ThreadTermHandler(int signo){
if (signo == SIGINT) {
printf("Ctrl+C detected !!! \n");
sem_post(&end);
}
}
void *func1()
{
int value;
for(;;){
sem_getvalue(&end, &value);
while(!value){
printf("in thread 1 \n");
}
}
return 0;
}
void *func2()
{
int value;
for(;;){
sem_getvalue(&end, &value);
while(!value){
printf("value = %d\n", value);
}
}
return 0;
}
int main(int argc, char *argv[])
{
sem_init(&end, 0, 0);
pthread_t th1,th2;
int value = -2;
pthread_create(&th1, NULL, func1, NULL);
pthread_create(&th2, NULL, func2, NULL);
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = ThreadTermHandler;
// Establish a handler to catch CTRL+c and use it for exiting.
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction for Thread Termination failed");
exit( EXIT_FAILURE );
}
/* Wait for SIGINT. */
while (sem_wait(&end)!=0){}
//{
printf("Terminating Threads.. \n");
sem_post(&end);
sem_getvalue(&end, &value);
/* SIGINT received, cancel threads. */
pthread_cancel(th1);
pthread_cancel(th2);
/* Join threads. */
pthread_join(th1, NULL);
pthread_join(th2, NULL);
//}
exit(0);
}发布于 2011-08-05 16:56:52
线程终止的方法主要有两种。
EINTR)。这两种方法都有警告。有关详细信息,请参阅消灭线程库中的线程。
在您的情况下,这似乎是一个使用取消点的好机会。我将使用一个注释的例子。为了清楚起见,错误检查被省略了.
#define _POSIX_C_SOURCE 200809L
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void sigint(int signo) {
(void)signo;
}
void *thread(void *argument) {
(void)argument;
for (;;) {
// Do something useful.
printf("Thread %u running.\n", *(unsigned int*)argument);
// sleep() is a cancellation point in this example.
sleep(1);
}
return NULL;
}
int main(void) {
// Block the SIGINT signal. The threads will inherit the signal mask.
// This will avoid them catching SIGINT instead of this thread.
sigset_t sigset, oldset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
pthread_sigmask(SIG_BLOCK, &sigset, &oldset);
// Spawn the two threads.
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, thread, &(unsigned int){1});
pthread_create(&thread2, NULL, thread, &(unsigned int){2});
// Install the signal handler for SIGINT.
struct sigaction s;
s.sa_handler = sigint;
sigemptyset(&s.sa_mask);
s.sa_flags = 0;
sigaction(SIGINT, &s, NULL);
// Restore the old signal mask only for this thread.
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
// Wait for SIGINT to arrive.
pause();
// Cancel both threads.
pthread_cancel(thread1);
pthread_cancel(thread2);
// Join both threads.
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
// Done.
puts("Terminated.");
return EXIT_SUCCESS;
}阻塞/解除阻塞信号的需要是,如果您向进程发送SIGINT,任何线程都可能捕获它。在生成线程之前,您可以这样做,以避免让它们自己执行并且需要与父线程同步。创建线程后,可以还原掩码并安装处理程序。
如果线程分配了大量资源,取消点可能会很棘手;在这种情况下,您将不得不使用pthread_cleanup_push()和pthread_cleanup_pop(),这两种情况都很混乱。但是,如果使用得当,这种方法是可行的,而且相当优雅。
发布于 2011-07-08 08:26:33
发布于 2011-07-08 08:30:01
您所做的一切都很有效,我认为它没有明显的问题(只是忽略了pthread_create的返回值)。不幸的是,停止线程比您可能认为的更复杂。事实上,你想要使用信号是另一个复杂的问题。这是你能做的。
pthread_sigmask阻止信号sigsuspend等待信号。pthread_cancel)子线程您的主线程可能如下所示:
/* Wait for SIGINT. */
sigsuspend(&mask);
/* SIGINT received, cancel threads. */
pthread_cancel(th1);
pthread_cancel(th2);
/* Join threads. */
pthread_join(th1, NULL);
pthread_join(th2, NULL);显然,您应该阅读更多关于pthread_cancel和取消点的内容。您还可以安装一个清理处理程序。当然,检查每个返回值。
https://stackoverflow.com/questions/6621785
复制相似问题