測試sigaction重啓動標識

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>linux

#include <iostream>ios

using namespace std;socket

bool flag = true;函數

static void sig_func(int signo){spa

  flag = false;
  cout<<"signal function called";
}.net


int main(){pwa

 

  struct sigaction newact, oldact;
  newact.sa_handler = sig_func;
  sigemptyset(&newact.sa_mask);
  newact.sa_flags = 0;
  newact.sa_flags |= SA_RESTART;接口

  sigaction(SIGINT, &newact, &oldact);隊列


//  signal(SIGINT, sig_func);get


  int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  int broad = 1;
  setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broad, sizeof(broad) );

  struct sockaddr_in addr;

  struct sockaddr_in addr2;
  socklen_t len = sizeof(addr2);

  memset(&addr, 0x00, sizeof(addr) );
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(3000);

  bind(sock, (struct sockaddr*)&addr, sizeof(addr) );
 
  while( true && flag){

    char msgbuf[1024];
    int nbytes = recvfrom(sock, msgbuf, sizeof(msgbuf), 0, (struct sockaddr*)&addr2, &len);

    if (nbytes < 0 && !flag){
      cerr<<"interrupted by ctrl c"<<endl;

    }

 


  }

 


  return 0;

}

 

若是在系統調用或者庫函數被阻塞的時候調用了信號處理函數,那麼庫函數和系統調用將會表現兩種狀況中的一種:

        一、在信號處理函數返回的時候自動重啓。

        二、調用失敗,errno被設置爲EINTR。

        具體表現爲那一種取決於調用的接口和信號處理函數在創建的時候是否使用SA_RESTART標誌。

        (1)若是一個被阻塞的調用是下面的接口中的一種,當它被信號處理函數打斷的時候,若是創建信號處理函數的時候使用SA_RESTART標誌,那麼它就會在信號處理函數返回的時候重啓,若是創建信號處理函數的時候沒有使用SA_RESTART,那麼調用就會失敗,並將errno置爲EINTR:

        在「慢」設備的上調用read(2),readv(2),write(2),writev(2),ioctl(2)。「慢」設備是指I/O調用可能阻塞無限長時間的設備,好比終端、管道、套接字。(根據這個定義,磁盤不是慢設備)。若是在慢設備上的I/O調用被信號處理函數中斷的時候已經傳輸了一些數據,那麼調用將返回正常狀態(一般是傳輸的字節數)。

        open(2),若是它可以被阻塞(例如,當打開FIFO的時候)。

        wait(2),wait3(2),wait4(2),waitid(2),waitpid(2)。

        若是套接字接口:accept(2),connect(2),recv(2),recvfrom(2),recvmsg(2),send(2),sendto(2),sendmsg(2)沒有設置timeout選項,他們也將自動重啓。

        文件鎖接口:flock(2),fcntl(2)使用F_SETLKW。

        POSIX 消息隊列接口:mq_receive(3), mq_timedreceive(3),mq_send(3), mq_timedsend(3)。

        futex(2) 使用FUTEX_WAIT(Linux 2.6.22以後纔有,以前老是返回EINTR錯誤)。

        POSIX信號量接口:sem_wait(3),sem_timedwait(3)(linux 2.6.22以後纔有,以前老是返回EINTR錯誤)。

 

        (2)下面的接口被信號處理函數中斷的時候從不重啓,並在被信號處理函數中斷的時候返回EINTR錯誤,而且忽略SA_RESTART標誌:

        套接字接口,當時使用setsockopt(2)設置了超時選項的時候:accept(2),recv(2),recvfrom(2),recvmsg(2)(若是接收超時標誌SO_RCVTIMEO被置),connect(2),send(2),sendto(2),sendmsg(2)(若是發送超時標誌SO_SNDTIMEO被設置)。

        用來等待信號的接口:pause(2),sigsuspend(2),sigtimedwait(2),sigwaitinfo(2)。

        文件描述符服用接口:epoll_wait(2),epoll_pwait(2),poll(2),ppoll(2),select(2),pselect(2)。

        System V IPC接口:msgrcv(2),msgsnd(2),semop(2),semtimedop(2)。

        sleep接口:clock_nanosleep(2),nanosleep(2),usleep(2)。

        read(2)一個inotify(7)文件描述符。

        io_getevents(2)。

        sleep(3)被信號處理函數中斷的時候也不會重啓,可是會返回成功,返回值是剩下還未睡眠的秒數。

相關文章
相關標籤/搜索