无名管道通信,只能用于父子进程间通信。
#include <unistd.h>
int pipe(int pipefd[2]);
当一个管道创建成功时,它会建立两个文件描述符。其中pipefd[0]用于读管道,pipefd[1]用于写管道。必须先pipe后fork,否则子进程将不会继承文件描述符
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main()
{
char buf_f[100];
pid_t pid;
memset(buf_f, 0, sizeof(buf_f));
int pipefd[2];
if (pipe(pipefd) < 0)
{
printf("Pipe create error!\n");
return -1;
}
pid = fork();
if (pid < 0)
printf("Fork Error!\n");
else if (pid == 0)
{
printf("This is the child process\n");
close(pipefd[1]);
sleep(2);
read(pipefd[0], buf_f, sizeof(buf_f));
printf("Get:%s\n", buf_f);
close(pipefd[0]);
}
else
{
printf("This is the father process\n");
close(pipefd[0]);
if (write(pipefd[1], "Hello Wanzi", 11) > 0)
printf("father write Hello Wanzi\n");
if (write(pipefd[1], "Goodbye Wanzi", 13) > 0)
printf("father write Goodbye Wanzi\n");
wait(NULL);
close(pipefd[1]);
}
return 0;
}
命名管道通信,可以用于任意两个进程间的通信。
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
打开fifo时,非阻塞标志(O_NONBLOCK)会控制进程在读不到数据时是否阻塞。
fifo_read.c
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#define FIFO_SERVER "/tmp/myfifo"
int main()
{
char buf[100];
int fd;
if ((mkfifo(FIFO_SERVER, O_CREAT | O_EXCL | 0700) < 0) &&
(errno != EEXIST)) //此处需要额外留意!!!创建管道文件时,权限问题很容易引起读写错误
printf("create fifo error!\n");
memset(buf, 0, sizeof(buf));
fd = open(FIFO_SERVER, O_RDONLY|O_NONBLOCK, 0);
if (fd == -1)
{
printf("open file error!!!!\n");
exit(1);
}
while (1)
{
if (read(fd, buf, 100) == -1)
{
if (errno == EAGAIN)
printf("no data yet\n");
}
printf("read %s from fifo!\n", buf);
sleep(1);
memset(buf, 0, sizeof(buf));
}
return 0;
}
fifo_write.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#define FIFO_SERVER "/tmp/myfifo"
int main(int argc, char** argv)
{
int fd = open(FIFO_SERVER, O_WRONLY|O_NONBLOCK);
char buf_f[100];
if (argc == 1)
{
printf("Please send sth\n");
exit(-1);
}
strcpy(buf_f, argv[1]);
if (write(fd, buf_f, sizeof(buf_f)) == -1)
{
if (errno == EAGAIN)
printf("ERROR!!!!!!!!!!!\n");
}
else
printf("send %s to fifo\n", buf_f);
return 0;
}
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
该函数用于关联信号与动作
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void my_func(int sig)
{
if (sig == SIGINT)
printf("Gotcha SIGINT!!!\n");
else if (sig == SIGQUIT)
printf("Gotcha SIGQUIT!!!\n");
}
int main()
{
printf("waiting for signals............\n");
signal(SIGINT, my_func);
signal(SIGQUIT, my_func);
pause();
return 0;
}
发送信号的主要函数有:kill()、raise()、 sigqueue()、alarm()、setitimer()以及abort()。