一, kill,alarm,abort函数的使用
kill函数的使用列子
/*************************************************************************
> File Name: kill.c
> Author: songli
> QQ: 2734030745
> Mail: 15850774503@163.com
> CSDN: http://my.csdn.net/Poisx
> github: https://github.com/chensongpoixs
> Created Time: Sun 22 Oct 2017 10:48:34 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
//pcb进程块pid
pid_t pid;
//创建子进程
pid = fork();
if (pid < 0) //异常处理
{
perror("fork error");
return -1;
}
else if (pid > 0) //父进程的处理
{
printf("fahter fpid:%d, cpid:%d\n", getpid(), pid);
while (1)
{
sleep(1);
}
}
else if (pid == 0) //子线程的处理
{
printf("child fpid:%d, cpid:%d\n", getppid(), getpid());
//子线程通知父线程
kill(getppid(), SIGKILL);
while (1)
{
sleep(1);
}
}
return 0;
}
raise函数的使用
/*************************************************************************
> File Name: raise.c
> Author: songli
> QQ: 2734030745
> Mail: 15850774503@163.com
> CSDN: http://my.csdn.net/Poisx
> github: https://github.com/chensongpoixs
> Created Time: Sun 22 Oct 2017 11:03:18 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
int main(int argc, char *argv[])
{
//PCB 进程块pid
pid_t pid;
//创建子进程
pid = fork();
if (pid < 0) //异常处理
{
perror("fork error");
return -1;
}
else if (pid > 0) //父进程的处理
{
printf("father fpid:%d, cpid:%d\n", getpid(), pid);
while (1)
{
sleep(1);
}
}
else if (pid == 0) //子线程的处理
{
printf("child fpid:%d, cpid:%d\n", getppid(), getpid());
//第一参数进程id 通知的进程id
int ret = raise(getppid());
if (ret == 0)
{
printf("ok\n");
}
while (1)
{
sleep(1);
}
}
return 0;
}
abort函数的使用
/*************************************************************************
> File Name: abort.c
> Author: songli
> QQ: 2734030745
> Mail: 15850774503@163.com
> CSDN: http://my.csdn.net/Poisx
> github: https://github.com/chensongpoixs
> Created Time: Sun 22 Oct 2017 11:13:43 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
//call back
void signalhandler(int signo)
{
printf("signo:%d\n", signo);
}
int main(int argc, char *argv[])
{
//定义信令集结构体赋值操作
struct sigaction act;
//回调函数的处理
act.sa_handler = signalhandler;
//清空未信令集的信令
sigemptyset(&act.sa_mask);
//赋值到block信令集中
sigaddset(&act.sa_mask, SIGABRT);
// 调用函数signal
// abort 函数的信号是 SIGABRT
sigaction(SIGABRT, &act, NULL);
abort();
return 0;
}
二,计时器的alarm和setitimer函数
alarm时候的使用
/*************************************************************************
> File Name: alarm.c
> Author: songli
> QQ: 2734030745
> Mail: 15850774503@163.com
> CSDN: http://my.csdn.net/Poisx
> github: https://github.com/chensongpoixs
> Created Time: Sun 22 Oct 2017 11:24:05 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
/**
*计时器的使用
*
*/
void signalhandler(int signo)
{
printf("signal:%d\n", signo);
}
int main(int argc, char *argv[])
{
// alarm 函数的signal是SIGALRM
signal(SIGALRM, signalhandler);
int ret;
//返回值的上一计时器的时间
alarm(1);
ret = alarm(3);
printf("ret :%d\n", ret);
sleep(5);
return 0;
}
setitimer函数的使用
/*************************************************************************
> File Name: setitimer.c
> Author: songli
> QQ: 2734030745
> Mail: 15850774503@163.com
> CSDN: http://my.csdn.net/Poisx
> github: https://github.com/chensongpoixs
> Created Time: Sun 22 Oct 2017 11:32:32 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
/**
*
*计时器的使用
*
*/
void signalhandler(int signo)
{
printf("signal:%d, 数据\n", signo );
}
int main(int argc, char *argv[])
{
//回调函数信令
signal(SIGALRM, signalhandler);
//周期函数的结构体
struct itimerval tm;
//设置周期
tm.it_interval.tv_sec = 1; //周期的设置
tm.it_interval.tv_usec = 0;
//下一个时间的周期
tm.it_value.tv_sec = 1;
tm.it_value.tv_usec = 0;
//计时器
setitimer(ITIMER_REAL, &tm, NULL );
while (1)
{
sleep(1);
}
return 0;
}
三,自定义信令集block信令集
函数
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
int sigprocmask(int how, const sigset_t *set, sigset_t *old‐
set);
信号集操作相关函数
1. 概念:
未决信号集:
没有被当前进程处理的信号
阻塞信号集:
将某个信号放到阻塞信号集,这个信号就不会被进程处理
阻塞解除之后,信号被处理
2. 自定义信号集
int sigemptyset(sigset_t *set); 将set集合置空
int sigfillset(sigset_t *set); 将所有信号加入set集合
int sigaddset(sigset_t *set,int signo);
§ 将signo信号加入到set集合
int sigdelset(sigset_t *set,int signo);
§ 从set集合中移除signo信号
int sigismember(const sigset_t *set,int signo);
§ 判断信号是否存在
3. sigprocmask函数
屏蔽或者是解除信号屏蔽, 将自定义信号集设置给阻塞信号集
函数原型:
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
4. sigpending – 读取当前进程的未决信号集
函数原型: int sigpending(sigset_t *set);
参数: set – 内核将未决信号集写入set
/*************************************************************************
> File Name: sigchld.c
> Author: songli
> QQ: 2734030745
> Mail: 15850774503@163.com
> CSDN: http://my.csdn.net/Poisx
> github: https://github.com/chensongpoixs
> Created Time: Sun 22 Oct 2017 11:51:31 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#define SIGPID 1
//call back
void signalhandler(int signo)
{
// PCB pid
pid_t wpid;
#if SIGPID
while (1)
{
#endif
wpid = waitpid(-1, NULL, WNOHANG);
if (wpid > 0) //退出子进程的操作
{
printf("退出子进程的操作:wpid:%d, signal:%d\n", wpid, signo);
}
else if (wpid == -1) // 没有子线程的操作
{
printf("没有子进程的操作:wpid:%d, signal:%d\n", wpid, signo);
exit(0);
}
else if (wpid == 0) //有子线程的操作
{
printf("有子进程的操作:wpid:%d, signal:%d\n", wpid, signo);
break;
}
#if SIGPID
}
#endif
}
int main(int argc, char *argv[])
{
//pcb 进程块 pid
pid_t pid;
int i, n = 3;
#if SIGPID
//设置阻塞信令集
sigset_t mask;
//清空信令集的数据
sigemptyset(&mask);
//赋值block信令集的操作
sigaddset(&mask, SIGCHLD);
//设置阻塞
sigprocmask(SIG_BLOCK, &mask, NULL);
#endif
for (i = 0; i < 3; i++)
{
//创建子进程
pid = fork();
if (pid < 0) //异常处理
{
perror("fork error");
return -1;
}
else if (pid > 0) //父进程的处理
{
printf("fahter fpid:%d, cpid:[%d]\n", getpid(), pid);
}
else if (pid == 0) // 子进程的处理
{
printf("child fpid:%d, cpid:[%d]\n", getppid(), getpid());
break; //防止子线程创建子线程
}
}
//============ 子线程操作 ===============
if (i < n)
{
printf("no child %d, cpid[%d]\n", i, getpid());
return 2;
}
//=========== 父进程的操作 ================
if (i == n)
{
printf("no father %d, fpid[%d]\n", i, getpid());
//信令结构体
struct sigaction act;
//回调函数
act.sa_handler = signalhandler;
//清空信令集的数据
sigemptyset(&act.sa_mask);
//赋值
sigaddset(&act.sa_mask, SIGCHLD);
sigaction(SIGCHLD, &act, NULL);
#if SIGPID
//解除block信令的阻塞事件
sigprocmask(SIG_UNBLOCK, &mask, NULL);
#endif
while (1)
{
sleep(1);
}
}
return 0;
}