简体   繁体   English

如何将 SIGINT 用于线程 C

[英]How to use SIGINT for threads C

I am trying to use SIGINT (CNTRL C) for threads but it is having a weird behavior.我正在尝试将 SIGINT (CNTRL C) 用于线程,但它的行为很奇怪。 I am trying to have a SIGINT function for the thread creator process and a SIGINT function for the threads themselves.我正在尝试为线程创建者进程设置一个 SIGINT function 并为线程本身设置一个 SIGINT function 。 Here is a sample code of what I am trying to achieve:这是我要实现的示例代码:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <semaphore.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>

pthread_t *cars;
 

void carEnd(){
  printf("Car from team %ld killed.\n",(long)getpid());
  pthread_exit(NULL);
}

void teamEnd(int signum){
  for(int j=0; j<3; j++){

    pthread_join(cars[j],NULL);
  }

  printf("Team %ld killed\n",(long)getpid());
  exit(0);
}

void *carThread(void* team_number){
  signal(SIGINT, carEnd);
  sleep(10);
  pthread_exit(NULL);
  return NULL;

}

int main(){
  signal(SIGINT, teamEnd);

  int workerId[3];

  pthread_t cars[3];

  //Create the car threads
  for(int i=0; i<3;i++){
    workerId[i] = i+1;
    pthread_create(&cars[i], NULL, carThread,&workerId[i]);
  }
  //Waits for all the cars to die
  for(int j=0; 3; j++){
    pthread_join(cars[j],NULL);
  }

  return 0;
}
`

After executing, if no SIGINT is detected the program closes after 10 seconds.执行后,如果未检测到 SIGINT,则程序会在 10 秒后关闭。 If a SIGINT is detected, then a single message "Car from team... killed" appears on the terminal.如果检测到 SIGINT,则终端上会显示一条消息“来自团队的汽车......已死亡”。 Would appreciate if anyone could explain me this behavior and how I can fix it to achieve my goal!如果有人能向我解释这种行为以及如何解决它以实现我的目标,我将不胜感激!

A Ctrl - C instructs your terminal to send a SIGINT to the foreground process group, meaning a SIGINT is generated for each process of the foreground group. Ctrl - C指示您的终端向前台进程组发送 SIGINT,这意味着为前台组的每个进程生成一个 SIGINT。

When a signal is generated for a process, the system attempts to deliver it to one and only one thread of that process.当为进程生成信号时,系统会尝试将其传递给该进程的一个且仅一个线程 In your example, all of your threads are eligible to receive the signal, since none have masked ("blocked") the signal as by pthread_sigmask .在您的示例中,您的所有线程都有资格接收信号,因为没有一个线程像pthread_sigmask那样屏蔽(“阻塞”)信号。 The system will choose one of the threads for signal delivery.系统将选择其中一个线程进行信号传递。

When the SIGINT is delivered to a thread, some action, known as the signal disposition, is taken.当 SIGINT 被传递到线程时,会采取一些称为信号处置的动作。 Importantly, a process can have one and only one disposition per signal at any given time — the most recent call to signal() or sigaction determines the disposition.重要的是,一个进程在任何给定时间每个信号都可以有一个且只有一个处置 - 最近对signal()sigaction的调用决定了处置。 So, your main() thread's chosen SIGINT disposition of teamEnd() is overwritten by the first of your carThread() threads to call signal() , and then redundantly overwritten by the rest of them.因此,您的main()线程选择的teamEnd()的 SIGINT 处置被您的第一个carThread()线程覆盖以调用signal() ,然后被其中的 rest 冗余覆盖。

In your case, the SIGINT happens to interrupt a carThread() during its sleep() , printing the message you see, and waking the thread which then terminates.在您的情况下, SIGINT 碰巧在carThread()期间中断sleep() ,打印您看到的消息,然后唤醒线程,然后终止。


Beyond the above, I cannot really say what you should do.除了上述之外,我真的不能说你应该做什么。 I think your goal is to gracefully terminate all threads upon SIGINT.认为您的目标是在 SIGINT 上优雅地终止所有线程。 If that's so, I'd suggest you do that by forcing the signal to be delivered to main() , and then having that thread instruct the others to quit via some shared flag or condition variable.如果是这样,我建议您通过强制将信号传递到main() ,然后让该线程指示其他线程通过某些共享标志或条件变量退出来做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM