1.無名管道
int pipe(int pipefd[2]);
- 條件:只適用于具有親緣關(guān)系的父子進程之間通信
- IO :文件IO
- 空間:無名管道在存在內(nèi)核區(qū)
- 阻塞:當管道為空讀端阻塞, 當管道為滿寫端阻塞
- 破裂:當讀端關(guān)閉,再次向管道寫數(shù)據(jù),管道破裂
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
int fd[2]; //fd[0]:讀端 fd[1]:寫端
char buf[32];
if(pipe(fd) == -1)
{
perror("pipe error");
exit(1);
}
pid_t pid = fork();
if(pid == -1)
{
perror("fork error");
exit(1);
}
else if(pid == 0)
{
//子:從終端讀取數(shù)據(jù),存到無名管道中
while(1)
{
fgets(buf, sizeof(buf), stdin);
write(fd[1], buf, 32);
if( strncmp(buf, "quit", 4) == 0)
{
exit(0);
}
}
}
else
{
//父:從無名管道讀取數(shù)據(jù),將數(shù)據(jù)打印到終端
while(1)
{
read(fd[0], buf, 32);
if(strncmp(buf, "quit", 4) == 0)
{
exit(0);
}
printf("-----> ");
fputs(buf, stdout);
}
}
return 0;
}
2.信號
#include <signal.h>
int kill(pid_t pid, int sig);
- 功能:向指定進程或進程組發(fā)送指定信號
- 參數(shù):pid > 0 :向指定進程發(fā)送一個信號
pid = 0 :向同組下的所有進程發(fā)送信號(包括自己)
pid = -1 :向可以發(fā)送的所有進程發(fā)送信號(除了1號進程)
pid < -1 :向指定進程組下的所有進程發(fā)送信號,PGID = -pid_t
sig:要發(fā)送的信號 - 返回:成功return 0; 失敗return -1;
int raise(int sig); 給進程本身發(fā)送一個sig信號
unsigned int alarm(unsigned int seconds);
- 功能:非阻塞模式,seconds秒之后發(fā)送SIGALRM信號給進程本身
新的alarm會覆蓋之前的alarm操作 - 返回:承接之前alarm()函數(shù)剩余的秒數(shù),作為返回值
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
- 功能:用于捕捉信號,設(shè)置信號的處理方式
- 注意:SIGKILL和SIGSTOP不可以被捕捉和忽略
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void handler(int sig) //捕捉到的信號傳遞給sig
{
if(sig == SIGINT)
{
puts("catch SIGINT");
}
if(sig == SIGTSTP)
{
puts("catch SIGTSTP");
}
}
int main(int argc, const char *argv[])
{
if(signal(SIGINT, handler) == SIG_ERR) //ctrl + c -->handler
{
perror("signal error");
exit(1);
}
if(signal(SIGTSTP, handler) == SIG_ERR) //ctrl + z -->handler
{
perror("signal error");
exit(1);
}
if(signal(SIGQUIT, SIG_DFL) == SIG_ERR) //ctrl + \ ---> 默認
{
perror("signal error");
exit(1);
}
printf("hello\n");
while(1);
return 0;
}