Advertisement
Guest User

example 3

a guest
Apr 8th, 2012
3,772
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.85 KB | None | 0 0
  1. #include <iostream>
  2. #include <pthread.h>
  3. #include <signal.h>
  4. #include <string.h>
  5. #include <poll.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8.  
  9. bool stop = false;
  10.  
  11. void hdl(int sig)
  12. {  
  13.     stop = true;
  14. }
  15.  
  16. void* blocking_read(void* arg)
  17. {
  18.     if(stop)
  19.     {
  20.         // не успели стартовать, а нас уже прикрыли ?
  21.         std::cout << "Thread was aborted\n";
  22.         pthread_exit((void *)0);
  23.     }
  24.        
  25.     // Блокируем сигнал SIGINT
  26.     sigset_t set, orig;
  27.     sigemptyset(&set);
  28.     sigaddset(&set, SIGINT);
  29.     sigemptyset(&orig);
  30.     pthread_sigmask(SIG_BLOCK, &set, &orig);
  31.    
  32.     if(stop)
  33.     {
  34.         // пока мы устанавливали блокировку сигнала он уже произошол
  35.         // возвращаем все как было и выходим
  36.         std::cout << "Thread was aborted\n";
  37.         pthread_sigmask(SIG_SETMASK, &orig, 0);
  38.         pthread_exit((void *)0);
  39.     }
  40.        
  41.     // Здесь нас не могут прервать сигналом SIGINT
  42.     std::cout << "Start thread to blocking read\n";
  43.     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  44.     const int optval = 1;
  45.     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
  46.     struct sockaddr_in addr;
  47.     bzero(&addr, sizeof(addr));
  48.     addr.sin_family = AF_INET;
  49.     addr.sin_port = htons(10000);
  50.     addr.sin_addr.s_addr = htonl(INADDR_ANY);
  51.     bind(sockfd, (sockaddr *)&addr, sizeof(addr));                                                      
  52.    
  53.     struct pollfd clients[1];
  54.     clients[0].fd = sockfd;
  55.     clients[0].events = POLLIN | POLLHUP;
  56.     clients[0].revents = 0;
  57.    
  58.     ppoll((struct pollfd*) &clients, 1, NULL, &orig);
  59.     // сдесь сигнал SIGINT все еще заблокирован
  60.    
  61.     if(stop)
  62.     {
  63.         // получили сигнал о завершении работы
  64.         std::cout << "Thread was aborted\n";
  65.         close(sockfd);
  66.         pthread_sigmask(SIG_SETMASK, &orig, 0);
  67.     }
  68.    
  69.     // Мы либо считали данные, либо произошла какаято ошибка. Но мы не получали
  70.     // сигнала о завершении работы и продолжаем работать "по плану"
  71.    
  72.     close(sockfd);  
  73.     pthread_exit((void *)0);  
  74. }
  75.  
  76. int main()
  77. {
  78.     std::cout << "Start application\n";
  79.     struct sigaction act;
  80.     memset(&act, 0, sizeof(act));
  81.     act.sa_handler = hdl;
  82.  
  83.     sigemptyset(&act.sa_mask);                                                            
  84.     sigaddset(&act.sa_mask, SIGINT);
  85.     sigaction(SIGINT, &act, 0);
  86.    
  87.     pthread_t th1;
  88.     pthread_create(&th1, NULL, blocking_read, NULL);
  89.     // даже если мы его впихнем тут, наш тред корректно завершится
  90.     //pthread_kill(th1, SIGINT);
  91.     sleep(1);
  92.  
  93.     std::cout << "Wait 5 seconds and stop\n";
  94.     sleep(5);
  95.     pthread_kill(th1, SIGINT);
  96.  
  97.     pthread_join(th1, NULL);
  98. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement