RTS 관련 질문입니다.
joinc의 강좌란에서 가져온 자료를 가지고 간단하게 구현한것인데요.
보시면 아시겠지만 간단히 쓰레드 하나 생성하고 그 쓰레드에서 listen
하고 있다가 연결 요청 들어오면 sigwaitinfo 에서 이벤트 처리를
하게끔 만들었습니다.
그런데 다음 이부분에서 에러가 납니다.
void * test (void *data) 함수내 ret = sigwaitinfo(&set, &si);
에러 실-시각 시그날
이러면서 종료가 되더군요.
그래서 main() 함수에서(주석처리부분) 쓰레드 생성하기전에 sigset_t 을
설정하고 해주니깐 에러가 발생하지 않더군요.
다른 질문이나 강좌란등을 찾아보면 모두 쓰레드내에서
설정해줘도 에러가 났다는 내용은 없더군요.
왜 그럴까요? 조언 부탁드립니다.
즐거운 하루 되세요~~
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
//#include <map>
#include <string>
#ifndef __USE_GNU
#define __USE_GNU
#endif
#include <fcntl.h>
#define SOCK_MAX_NUM 1024
//using namespace std;
// 듣기 소켓 저장용
static int listen_sockfd;
/*
* 인자로 주어진 파일지정자 fd에 대해서
* RTS대응하도록 만든다.
*/
int setup_sigio(int fd)
{
if (fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) < 0)
{
printf("Nonblocking error\n");
return -1;
}
if (fcntl(fd, F_SETSIG, SIGRTMIN) < 0)
{
printf("Couldn't set signal %d on %d\n", SIGRTMIN, fd);
return -1;
}
if (fcntl(fd, F_SETOWN, getpid()) < 0)
{
printf("Could'nt set owner %d on %d\n", getpid(), fd);
return -1;
}
return 0;
}
/*
* 듣기 소켓(endpoint socket)를 생성하고
* 만들어진 듣기 소켓에 대해서 RTS대응 하도록 한다.
* 일반적인 socket -> bind -> listen 과정을 거친다.
*/
int get_listener_fd()
{
int clilen;
int state;
struct sockaddr_in serveraddr;
clilen = sizeof(serveraddr) ;
listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sockfd < 0)
{
printf("Socket create error\n");
return -1;
}
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(7777);
state = bind (listen_sockfd, (struct sockaddr *)&serveraddr,
sizeof(serveraddr));
if (state < 0)
{
printf("Bind error\n");
return -1;
}
state = listen(listen_sockfd, 5);
if (state < 0)
{
printf("Listen error\n");
return -1;
}
printf("Listen Socket Create %d\n", listen_sockfd);
return setup_sigio(listen_sockfd);
}
void * test (void *data)
{
struct siginfo si;
int clilen;
int ret;
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGRTMIN+1);
pthread_sigmask(SIG_BLOCK, &set, NULL);
// 듣기 소켓을 생성한다.
if(get_listener_fd() < 0)
{
printf("Socket Create error\n");
exit(0);
}
while(1)
{
printf("before sigwaitinfo \n");
// 소켓으로 부터 이벤트를 기다린다.
// Error 발생 ..
ret = sigwaitinfo(&set, &si);
printf("after sigwaitinfo \n");
if (ret == SIGRTMIN+1)
{
// 만약 듣기 소켓에 발생한 이벤트라면
// accept(2)를 호출해서 연결 소켓을 생성한다.
if (si.si_fd == listen_sockfd)
{
printf("ok signal %d %d\n", si.si_fd, si.si_code);
}
else
{
printf("socket event \n");
}
}
}
}
int main()
{
/*static sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGRTMIN+1);
pthread_sigmask(SIG_BLOCK, &set, NULL);*/
pthread_t *blah;
if( !(blah=calloc(1,sizeof(pthread_t)))) return NULL;
if(pthread_create(blah,NULL,test,NULL)) {
free(blah);
return NULL;
}
pthread_join(blah, NULL);
free(blah);
return 0;
}
댓글 달기