进程的创建
fork()
,当返回值为0时,代表为子进程,当返回值为1时,代表为父进程。。用以区分子父进程的作用。。
- 僵尸进程的产生:
子进程结束后,父进程还在继续运行但是并未调用wait/waitpid那子进程就会成为僵尸进程即子进程在父进程之前退出 - 如何防止僵尸进程
避免僵尸进程主要包含以下几种方法:
1、父进程使用wait()
或者waitpid()
之类的函数等待子进程退出
2、父进程先产生一个子进程,然后子进程再产生一个孙子进程,子进程在孙子进程之前退出。
3、使用信号函数sigaction
为SIGCHLD
设置wai
t处理函数。
- 在父进程中为
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());
}
}
- 创建一个子进程,子进程进入一个无限循环,模拟每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);
if((pid = fork()) == 0)
{
signal(SIGINT, SIG_IGN);
signal(SIGUSR1, child_process_sig_handler);
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函数向指定进程发送指定信号值
// 注意,信号发送无法传递数据
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);
}
}
// 实现原理:当子进程退出时,会向父进程发送SIGCHLD
信号,在父进程的SIGCHLD
信号处理函数中调用wait
函数,防止僵尸进程的产生
注意:本例使用信号异步处理僵尸进程
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <stdlib.h>
// 信号处理函数能够使用其形式参数接收触发该函数的信号值
void sig_handler(int signo);
int main(int argc, char *argv[])
{
pid_t pid;
srand(time(NULL));
// sigaction
signal(SIGCHLD, sig_handler);
while(1)
{
pid = fork();
if(pid == 0)
{
printf("child process %d is running...\n", getpid());
sleep(rand()%3+1);
//return 0;
exit(0);
}
else if(pid > 0)
{
sleep(1);
}
}
return 0;
}
// 信号处理函数能够使用其形式参数接收触发该函数的信号值
void sig_handler(int signo)
{
if(signo == SIGCHLD)
{
printf("child process %d is exit!!!\n",
wait(NULL));
}
}
- 创建线程的三个函数
pthread_create()
pthread_join()
pthead_exit()
#include<stdio.h>
#include<pthread.h>
void *pthread_func(void *arg);
int main(int argc,char *argv[])
{
pthread_t pthread_id;
pthread_create(&pthread_id,NULL,&pthread_func,NULL);
printf("hahahaha__main\n");
pthread_join(&pthread_id,NULL);
return 0;
}
void *pthread_func(void *arg)
{
printf("hahaha\n");
pthread_exit(NULL);
}
网友评论