信号(六)

一、sigqueue函数

(1)功能:新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用。

(2)原型: int sigqueue(pid_t pid, int sig, const union sigval value);

(3)参数:sigqueue的第一个参数是指定接收信号的进程id,第二个参数确定即将发送的信号,第三个参数是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。

(4)返回值:成功返回0,失败返回-1

二、sigval联合体

typedef union sigval
 { 
	int sival_int; 
	void *sival_ptr; 
}sigval_t; 

第一个例子:

sigaciton结构体的sa_flags需要设置SA_SIGINFO才可以接收数据

sigaction_recv.c

#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>

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


#define ERR_EXIT(m) \
	do \
	{ \
		perror(m); \
		exit(EXIT_FAILURE); \
	} while(0)

void handler(int, siginfo_t *, void *);

int main(int argc, char *argv[])
{
	struct sigaction act;
	act.sa_sigaction = handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = SA_SIGINFO;

	if (sigaction(SIGINT, &act, NULL) < 0)
		ERR_EXIT("sigaction error");

	for (;;)
		pause();
	return 0;
}

void handler(int sig, siginfo_t *info, void *ctx)
{
	printf("recv a sig=%d data=%d data=%d\n", sig, info->si_value.sival_int, info->si_int);
}

sigqueue_send.c

#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>

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


#define ERR_EXIT(m) \
	do \
	{ \
		perror(m); \
		exit(EXIT_FAILURE); \
	} while(0)

int main(int argc, char *argv[])
{
	if (argc != 2)
	{
		fprintf(stderr, "Usage %s pid\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	pid_t pid = atoi(argv[1]);
	union sigval v;
	v.sival_int = 100;
	sigqueue(pid, SIGINT, v);
	return 0;
}

第二个例子:

sigaction_recv.c

当收到SIGQUIT信号设置进程SIGINT,SIGRTMIN信号屏蔽字为0,SIGINT为不可靠信号,不支持排队,会丢失,SIGRTMIN是可靠信号,支持排队

向sigqueue_recv进程发送信号

sigaction_recv进程接收信号

#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>

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


#define ERR_EXIT(m) \
	do \
	{ \
		perror(m); \
		exit(EXIT_FAILURE); \
	} while(0)

void handler(int);

int main(int argc, char *argv[])
{
	struct sigaction act;
	act.sa_handler = handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;

	sigset_t s;
	sigemptyset(&s);
	sigaddset(&s, SIGINT);
	sigaddset(&s, SIGRTMIN);
	sigprocmask(SIG_BLOCK, &s, NULL);
	if (sigaction(SIGINT, &act, NULL) < 0)
		ERR_EXIT("sigaction error");

	if (sigaction(SIGRTMIN, &act, NULL) < 0)
		ERR_EXIT("sigaction error");

	if (sigaction(SIGUSR1, &act, NULL) < 0)
		ERR_EXIT("sigaction error");
	for (;;)
		pause();
	return 0;
}

void handler(int sig)
{
	if (sig == SIGINT || sig == SIGRTMIN)
		printf("recv a sig=%d\n", sig);
	else if (sig == SIGUSR1)
	{
		sigset_t s;
		sigemptyset(&s);
		sigaddset(&s, SIGINT);
		sigaddset(&s, SIGRTMIN);
		sigprocmask(SIG_UNBLOCK, &s, NULL);
	}
}

sigqueue_send.c

​
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>

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


#define ERR_EXIT(m) \
	do \
	{ \
		perror(m); \
		exit(EXIT_FAILURE); \
	} while(0)

int main(int argc, char *argv[])
{
	if (argc != 2)
	{
		fprintf(stderr, "Usage %s pid\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	pid_t pid = atoi(argv[1]);
	union sigval v;
	v.sival_int = 100;
	sigqueue(pid, SIGINT, v);
	sigqueue(pid, SIGINT, v);
	sigqueue(pid, SIGINT, v);
	sigqueue(pid, SIGRTMIN, v);
	sigqueue(pid, SIGRTMIN, v);
	sigqueue(pid, SIGRTMIN, v);
	sleep(3);
	kill(pid, SIGUSR1);
	return 0;
}

​

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值