进程:
1、进程的五大状态
// 练习1:在父进程中为SIGINT信号注册处理函数,然后创建一个子进程,父子进程均进行无限循环,使用Ctrl+c组合键触发SIGINT信号,观察父子进程的执行情况
// 注意:子进程在创建时会copy当前父进程的信号处理方式
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sig_handler(int signo);
int main(int argc, char *argv[])
{
pid_t pid;
struct sigaction act;
//signal(SIGINT, SIG_IGN);
//signal(SIGINT, SIG_DFL);
//signal(SIGINT, sig_handler);
act.sa_handler = sig_handler;
//act.sa_handler = SIG_IGN;
//act.sa_handler = SIG_DFL;
sigaction(SIGINT, &act, NULL);
pid = fork();
while(1);
return 0;
}
void sig_handler(int signo)
{
switch(signo)
{
case SIGINT:
printf("signal SIGINT catched in process %d\n", getpid());
}
}
// 练习2:创建一个子进程,子进程进入一个无限循环,模拟每1秒从数据中心取一个数据并处理的过程,直到子进程收到父进程发送过来的SIGUSR1信号,打印子进程pid,并退出
// 父进程:创建子进程之后,循环等待信号的到达,当收到SIGINT(由组合键Ctrl+c模拟)信号之后,向子进程发送一个SIGUSR1信号
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
pid_t pid;
void parent_process_sig_handler(int signo);
void child_process_sig_handler(int signo);
int main(int argc, char *argv[])
{
signal(SIGINT, parent_process_sig_handler);
signal(SIGCHLD, parent_process_sig_handler);
printf("first:%d\n",getpid());
if((pid = fork()) == 0)
{
signal(SIGINT, SIG_IGN);
signal(SIGUSR1, child_process_sig_handler);
printf("child:%d\n",getpid());
printf("child->father:%d\n",getppid());
int client_id = 0;
while(1)
{
client_id = rand()%100+1;
printf("client %d is in...\n", client_id);
sleep(1);
printf("client %d is out...\n", client_id);
}
}
else if(pid > 0)
{
while(1);
}
else
{
}
return 0;
}
void parent_process_sig_handler(int signo)
{
switch(signo)
{
case SIGCHLD:
wait(NULL);
break;
case SIGINT:
// kill函数向指定进程发送指定信号值
// 注意,信号发送无法传递数据
printf("before kill:%d\n",getpid());
kill(pid, SIGUSR1);
break;
default:
break;
}
}
void child_process_sig_handler(int signo)
{
if(signo == SIGUSR1)
{
printf("child process pid : %d\n", getpid());
exit(0);
}
}