리눅스 프로그램 중입니다.
signal이나 sigaction을 이용해서 이벤트가 발생하면 지정한 액션을 하도록 할 수 있다고 책에 나와있군요. (오늘 첨 봤음 ^&^) 그런데 이때 실행되는 함수에 전달되는 인자는 시그널 번호뿐이군요. 뭔가 다른 인자를 전달하고 싶은데 방법이 없는지요? 물론 전역변수는 가능하겠지만 이거 말고 인자를 전달하는 방법이 궁금합니다.
일단은 없다고 봐야 합니다.
시그널 핸들러 자체가 이미 원형이 정해진 상태이기 때문에 그 원형을 마음대로 바꾸려면 결국은 커널까지 건드려야죠.
하지만 편법으로 시그널 핸들러에 인자를 전달하는 방법이 있긴 합니다.
말씀하신대로 전역변수를 사용한다던지 하는 방식으로 말이죠.
저같은 경우는 시그널을 보내기 전에 메세지큐에 인자로 사용될 값들을 넣어두고 시그널을 보내고, 시그널을 받는 쪽에서는 시그널 핸들러 안에서 메세지큐에 있는 값을 읽어와 사용하는 방식을 사용합니다.
sigaction함수의 두번째 인자인 siginfo_t 구조체에 int값을 실어서 전달할수 있습니다.
siginfo_t {
int si_signo; /* 시그널 넘버 */
int si_errno; /* errno 값 */
int si_code; /* 시그널 코드 */
pid_t si_pid; /* 프로세스 ID 보내기 */
uid_t si_uid; /* 프로세스를 전송하는 실제 사용자 ID */
int si_status; /* Exit 값 또는 시그널 */
clock_t si_utime; /* 소모된 사용자 시간 */
clock_t si_stime; /* 소모된 시스템 시간 */
sigval_t si_value; /* 시그널 값 */
int si_int; /* POSIX.1b 시그널 */
void * si_ptr; /* POSIX.1b 시그널 */
void * si_addr; /* 실패를 초래한 메모리 위치 */
int si_band; /* 밴드 이벤트 */
int si_fd; /* 파일 기술자 */
}
[RE]
일단은 없다고 봐야 합니다.
시그널 핸들러 자체가 이미 원형이 정해진 상태이기 때문에 그 원형을 마음대로 바꾸려면 결국은 커널까지 건드려야죠.
하지만 편법으로 시그널 핸들러에 인자를 전달하는 방법이 있긴 합니다.
말씀하신대로 전역변수를 사용한다던지 하는 방식으로 말이죠.
저같은 경우는 시그널을 보내기 전에 메세지큐에 인자로 사용될 값들을 넣어두고 시그널을 보내고, 시그널을 받는 쪽에서는 시그널 핸들러 안에서 메세지큐에 있는 값을 읽어와 사용하는 방식을 사용합니다.
sigaction함수의 두번째
sigaction함수의 두번째 인자인 siginfo_t 구조체에 int값을 실어서 전달할수 있습니다.
siginfo_t {
int si_signo; /* 시그널 넘버 */
int si_errno; /* errno 값 */
int si_code; /* 시그널 코드 */
pid_t si_pid; /* 프로세스 ID 보내기 */
uid_t si_uid; /* 프로세스를 전송하는 실제 사용자 ID */
int si_status; /* Exit 값 또는 시그널 */
clock_t si_utime; /* 소모된 사용자 시간 */
clock_t si_stime; /* 소모된 시스템 시간 */
sigval_t si_value; /* 시그널 값 */
int si_int; /* POSIX.1b 시그널 */
void * si_ptr; /* POSIX.1b 시그널 */
void * si_addr; /* 실패를 초래한 메모리 위치 */
int si_band; /* 밴드 이벤트 */
int si_fd; /* 파일 기술자 */
}
시그널을 발생하는 프로세서에서의 예
void emit_signal()
{
sigval s;
s.sival_int = 55; <-사용자의 전달값
sigqueue( pid_a, SIGUSR1, s ); <-시그널을 받을 프로세스의 pid, 발생할 signal종류, sigval구조체
}
시그널을 받는쪽에서는 SIGUSR1을 캐치해서 두번째 인자의 sival_int값을 보면 55가 전달된것을 확인하실수 있을겁니다.
댓글 달기