作用:
给指定进程发送指定信号(不一定是杀死)
语法:
头文件:
#include
#include
函数:
int kill(pid_t pid, int sig);
参数:
返回值:
成功:0
失败:-1
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
pid_t pid = fork();
if(pid == 0){
while (1)
{
printf("找打、\n");
sleep(1);
}
}else if(pid > 0){
printf("给你三秒、\n");
sleep(3);
kill(pid,SIGKILL);
}
return 0;
}
#include
#include
#include
int main(int argc, char const *argv[])
{
int i = 0;
while (1)
{
sleep(1);
printf("好无聊哦,%d\n", i);
if (i == 3)
{
printf("死给你看\n");
raise(SIGKILL);
}
i++;
}
return 0;
}
#include
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
/*
指针数组,存储指针的数组
本质上是一个数组,该数组中存储的是指针
定义语法:数据类型 *指针变量名[长度];
数组指针
本质上是个指针
定义语法:指向的数组的类型(*指针变量名)[指向的数组的元素个数]
*/
char *myinfos[3] = {"我要发信号了", "我真的要发信号了", "拜拜咯,下次见"};
int i = 0;
while (1)
{
char * info = myinfos[i];
printf("%s\n",info);
sleep(1);
i++;
if(i == 3){
abort();
}
}
return 0;
}
作用:
设置定时器(闹钟),在指定时间后(单位:秒),内核会给当前进程发送SIGALRM信号,默认动作终止进程,每个进程都有且只有一个定时器。
取消定时器alarm(0);返回旧闹钟余下的秒数
头文件:
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
int tim = 0;
tim = alarm(5);
printf("倒计时 %d\n",tim);
sleep(1);
tim = alarm(5);
printf("倒计时 %d\n",tim);
while (1)
{
/* code */
}
return 0;
}
#include
#include
#include
void fun()
{
printf("已处理\n");
}
int main(int argc, char const *argv[])
{
struct itimerval new_v;
new_v.it_value.tv_sec = 5;
new_v.it_value.tv_usec = 0;
new_v.it_interval.tv_sec = 1;
new_v.it_interval.tv_usec = 0;
signal(SIGALRM, fun); // 信号处理
setitimer(ITIMER_REAL, &new_v, NULL); // 定时器设置
while (1)
;
return 0;
}
#include
#include
#include
void fun()
{
printf("已处理\n");
}
int main(int argc, char const *argv[])
{
printf("进程以开始,当前进程:%d\n", getpid());
signal(SIGALRM, fun);
alarm(3);
int x = pause();
printf("进程结束%d\n", x);
return 0;
}
#include
#include
#include
void myfun(int sigcode)
{
printf("自定义函数\n");
_exit(-1);
}
int main(int argc, char const *argv[])
{
// ctrl+c发出的信息为SIGINT
signal(SIGINT, myfun);
while (1)
;
return 0;
}
#include
#include
#include
#include
#include
char *p;
void myfun(int sigcode)
{
if (p != NULL)
{
free(p);
}
printf("p的空间被释放了\n");
_exit(-1);
}
int main(int argc, char const *argv[])
{
p = malloc(50);
strcpy(p, "helloSIG");
signal(SIGINT, myfun);
while (1)
{
printf("%s\n", p);
sleep(1);
}
return 0;
}
注意:
struct sigaction
{
void (*sa_handler)(int); // 旧的信号处理函数指针
void (*sa_sigaction)(int, siginfo_t *, void *); // 新的信号处理函数指针
sigset_t sa_mask; // 信号阻塞集
int sa_flags; // 信号处理的方式
void (*sa_restorer)(void); // 已弃用
};
/*
1,sa_handler,sa_sigaction:信号处理函数指针,和signal()里的函数指针用法
一样,应根据情况给 sa_sigaction、sa_handler 两者之一赋值,其取值如下:
a SIGIGN:忽略该信号
b SIGDFL:执行系统默认动作
c 处理函数名:自定义信号处理函数
2,sa_mask:信号阻塞集,在信号处理函数执行过程中,临时屏蔽指定的信号。
3,sa_flags:用于指定信号处理的行为,通常设置为 0,表使用默认属性。它可
以是以下值的“按位或”组合:
SA_RESTART:使被信号打断的系统调用自动重新发起(已经废弃)
SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD
信号。
SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这
时子进程如果退出也不会成为僵尸进程。
SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这
个信号。
SA_RESETHAND:信号处理之后重新设置为默认的处理方式。
SA_SIGINFO:使用 sa_sigaction 成员而不是 sa_handler 作为信号处理
函数
void(*sa_sigaction)(int signum, siginfo_t *info, void *context);
参数说明:
signum:信号的编号。
info:记录信号发送进程信息的结构体。
context:可以赋给指向ucontext_t类型的一个对象的指针,以引用在传递信
号时被中断的接收进程或线程的上下文。
*/
示例:
#include
#include
#include
#include
#include
void myfunc(int sigcode)
{
printf("ctrl+c的信号编码是:%d\n", sigcode);
_exit(-1);
}
int main(int argc, char const *argv[])
{
struct sigaction act;
act.sa_handler = myfunc;
sigaction(SIGINT, &act, NULL);
while (1)
;
return 0;
}
#include
#include
#include
#include
#include
#include
void myfunc(int sigcode)
{
printf("SIGUSR1信号编号是:%d\n", sigcode);
_exit(-1);
}
int main(int argc, char const *argv[])
{
// 注意vscode中变量名会报错,不用管
struct sigaction act;
act.sa_handler = myfunc;
// 注册监听的信号
sigaction(SIGUSR1, &act, NULL);
// 发出自定义信号
kill(getpid(), SIGUSR1);
while (1)
;
return 0;
}
#include
#include
#include
#include
#include
void show(int pid)
{
for (int i = 0; i < 3; i++)
{
char buf[50] = {0};
sprintf(buf, "进程%d第%d次执行%s", pid, i, "\r\n");
write(1, buf, sizeof(buf));
sleep(1);
}
}
int main(int argc, char const *argv[])
{
for (int i = 0; i < 5; i++)
{
int pid = fork();
if (pid == 0)
{
show(getpid());
_exit(0);
}
else if (pid > 0)
{
printf("子进程%d被创建了\n", pid);
}
}
while (1)
{
int id = waitpid(-1, NULL, WNOHANG);
if (id > 0)
{
printf("进程%d被回收\n", id);
}
else if (id == -1)
{
break;
}
}
return 0;
}
#include
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
// 定义一个信号集
sigset_t set;
// 清空set集
sigemptyset(&set);
// 将SIGINT添加到set集合中
sigaddset(&set, SIGINT);
// 将SIGTSTP添加到set集和中
sigaddset(&set, SIGTSTP);
if (sigismember(&set, SIGINT))
{
printf("SIGINT是在set集合中\n");
}
else
{
printf("SIGINT不在set集合中\n");
}
// 将SIGINT从集合中删除
sigdelset(&set, SIGINT);
if (sigismember(&set, SIGINT))
{
printf("SIGINT是在set集合中\n");
}
else
{
printf("SIGINT不在set集合中\n");
}
return 0;
}
#include
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
// 定义一个信号集
// vscode中编写的sigset_t会报错,不管
sigset_t set;
// 清空set集
sigemptyset(&set);
// 将SIGINT添加到set集合中
sigaddset(&set, SIGINT);
// 将set集合添加到阻塞集
// vscode中编写的SIG_BLOCK,SIG_BLOCK会报错不管
sigprocmask(SIG_BLOCK, &set, NULL);
printf("SIGINT信号将在5秒后从阻塞集中删除\n");
sleep(5);
sigprocmask(SIG_UNBLOCK, &set, NULL);
while (1)
;
return 0;
}