gpt4 book ai didi

c - POSIX pthread 编程

转载 作者:太空狗 更新时间:2023-10-29 16:42:43 26 4
gpt4 key购买 nike

我必须编写一个多线程(比如 2 个线程)程序,其中每个线程执行不同的任务。此外,这些线程一旦启动就必须在后台无限运行。这是我所做的。如果方法不错并且您发现了一些问题,有人可以给我一些反馈吗?另外,我想知道一旦我使用 Ctrl+C 终止执行,如何以系统的方式关闭线程。

main 函数创建了两个线程,并让它们无限运行,如下所示。

这是骨架:

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);
}

最佳答案

线程终止主要有两种方法。

  • 使用取消点。线程将在请求取消时终止并且它到达取消点,从而以受控方式结束执行;
  • 使用信号。让线程安装信号处理程序,它提供终止机制(设置标志并对 EINTR 作出 react )。

这两种方法都有注意事项。引用Kill Thread in Pthread Library了解更多详情。

在您的情况下,这似乎是使用取消点的好机会。我将使用一个注释示例。为清楚起见,省略了错误检查。

#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(),它们是一团糟。但如果使用得当,这种方法是可行的,而且相当优雅。

关于c - POSIX pthread 编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6621785/

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