通过无名管道,让两个子进程间完成相互通信工作
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
int pipefd[2] = {0};
int ret = -1;
ret = pipe(pipefd);
if (-1 == ret)
{
perror("pipe");
return -1;
}
pid_t pid = fork();
if (pid > 0) //parent
{
pid_t pid2 = fork();
if (pid2 > 0)
{
waitpid(pid, NULL, 0);
waitpid(pid2, NULL, 0);
}
else if (0 == pid2)
{
int iSign = 0;
char caBuf[64] = {'\0'};
while (1)
{
memset(caBuf, '\0', sizeof(caBuf));
if (0 == iSign)
{
printf("second-input data:");
scanf("%s", caBuf);
write(pipefd[1], caBuf, strlen(caBuf));
iSign = 1;
}
else if (1 == iSign)
{
read(pipefd[0], caBuf, sizeof(caBuf));
printf("first says:%s\n", caBuf);
iSign = 0;
}
sleep(1);
}
}
else if (-1 == pid2)
{
perror("second fork");
return -1;
}
}
else if (0 == pid) //child
{
int iSign = 0;
char caBuf[64] = {'\0'};
while (1)
{
memset(caBuf, '\0', sizeof(caBuf));
if (0 == iSign)
{
read(pipefd[0], caBuf, sizeof(caBuf));
printf("second says:%s\n", caBuf);
iSign = 1;
}
else if (1 == iSign)
{
printf("first-input data:");
scanf("%s", caBuf);
write(pipefd[1], caBuf, strlen(caBuf));
iSign = 0;
}
sleep(1);
}
}
else if (-1 == pid) //error
{
perror("first fork");
return -1;
}
return 0;
}
运行结果:
捕获.PNG
命名管道和一般的管道基本相同,区别:
1,命名管道在文件系统中作为一个特殊的设备文件而存在
2,不同祖先的进程之间可以通过管道共享数据
3,当所有使用到管道的进程执行完IO操作后,
命名管道并不会销毁,
而是继续保存在文件系统中以便后面使用
fifo.png
chat_fifo.c(chat_fifo.c和2chat_fifo.c通信)
/*mkfifo(): a named pipe*/
#include <sys/types.h>
#include <sys/stat.h>
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h> //perror() strerror()
#include <errno.h> //errno
#include <stdlib.h>
#include <unistd.h>
#define FIFO_PATHNAME "myFifo"
int main(void)
{
int ret = -1;
ret = mkfifo(FIFO_PATHNAME, 0777);
if (-1 == ret)
{
if (EEXIST != errno)
{
perror("mkfifo");
exit(EXIT_FAILURE);
}
}
printf("fifo is ok\n");
int fd = -1;
fd = open(FIFO_PATHNAME, O_RDWR);
if (-1 == fd)
{
perror("open");
exit(EXIT_FAILURE);
}
int iSign = 0;
char caBuf[32] = {'\0'};
while (1)
{
memset(caBuf, '\0', sizeof(caBuf));
if (0 == iSign)
{
printf("1,please input data:");
scanf("%s", caBuf);
ret = write(fd, caBuf, strlen(caBuf));
if (-1 == ret)
{
perror("write");
exit(EXIT_FAILURE);
}
iSign = 1;
sleep(1);
}
else if (1 == iSign)
{
ret = read(fd, caBuf, sizeof(caBuf));
if (-1 == ret)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("1,receive data: %s\n", caBuf);
iSign = 0;
}
}
close(fd);
return 0;
}
2chat_fifo.c
/*mkfifo(): a named pipe*/
#include <sys/types.h>
#include <sys/stat.h>
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h> //perror() strerror()
#include <errno.h> //errno
#include <stdlib.h>
#include <unistd.h>
#define FIFO_PATHNAME "myFifo"
int main(void)
{
int ret = -1;
ret = mkfifo(FIFO_PATHNAME, 0777);
if (-1 == ret)
{
if (EEXIST != errno)
{
perror("mkfifo");
exit(EXIT_FAILURE);
}
}
printf("fifo is ok\n");
int fd = -1;
fd = open(FIFO_PATHNAME, O_RDWR);
if (-1 == fd)
{
perror("open");
exit(EXIT_FAILURE);
}
int iSign = 0;
char caBuf[32] = {'\0'};
while (1)
{
memset(caBuf, '\0', sizeof(caBuf));
if (0 == iSign)
{
ret = read(fd, caBuf, sizeof(caBuf));
if (-1 == ret)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("2,receive data: %s\n", caBuf);
iSign = 1;
}
else if (1 == iSign)
{
printf("2,please input data:");
scanf("%s", caBuf);
ret = write(fd, caBuf, strlen(caBuf));
if (-1 == ret)
{
perror("write");
exit(EXIT_FAILURE);
}
iSign = 0;
sleep(1);
}
}
close(fd);
return 0;
}
运行结果:
chat_fifo.c(先写).PNG 2chat_fifo.c(先读).PNG
writ_fifo.c
/*mkfifo(): a named pipe*/
#include <sys/types.h>
#include <sys/stat.h>
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h> //perror() strerror()
#include <errno.h> //errno
#include <stdlib.h>
#include <unistd.h>
#define FIFO_PATHNAME "myFifo"
int main(void)
{
int ret = -1;
ret = mkfifo(FIFO_PATHNAME, 0777);
if (-1 == ret)
{
if (EEXIST != errno)
{
perror("mkfifo");
exit(EXIT_FAILURE);
}
}
printf("fifo is ok\n");
int fd = -1;
fd = open(FIFO_PATHNAME, O_WRONLY);
if (-1 == fd)
{
perror("open");
exit(EXIT_FAILURE);
}
ret = write(fd, "Hello World", 11);
if (ret > 0)
{
printf("write %d bytes to fifo\n", ret);
}
close(fd);
return 0;
}
运行结果:
write_fifo.PNG
read_fifo.c
/*mkfifo(): a named pipe*/
#include <sys/types.h>
#include <sys/stat.h>
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h> //perror() strerror()
#include <errno.h> //errno
#include <stdlib.h>
#include <unistd.h>
#define FIFO_PATHNAME "myFifo"
int main(void)
{
int ret = -1;
//创建命名管道:
//第一个参数:管道的路径名
//第二个参数:操作管道的权限
ret = mkfifo(FIFO_PATHNAME, 0777);
//创建管道成功返回0,失败返回-1
if (-1 == ret)
{
if (EEXIST != errno)
{
perror("mkfifo");
exit(EXIT_FAILURE);
}
}
printf("fifo is ok\n");
//管道创建成功后,可以像普通文件一样操作
//open,read,write,close
int fd = -1;
fd = open(FIFO_PATHNAME, O_RDONLY);
if (-1 == fd)
{
perror("open");
exit(EXIT_FAILURE);
}
char caBuf[64] = {'\0'};
//管道中的数据经过读操作之后就没了
ret = read(fd, caBuf, sizeof(caBuf));
if (ret > 0)
{
printf("%s\n", caBuf);
printf("read %d bytes from fifo\n", ret);
}
close(fd);
return 0;
}
运行结果:
read_fifo.PNGtest.c
/*mkfifo(): a named pipe*/
#include <sys/types.h>
#include <sys/stat.h>
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h> //perror() strerror()
#include <errno.h> //errno
#include <stdlib.h>
#include <unistd.h>
#define FIFO_PATHNAME "fifo.txt"
int main(void)
{
int ret = -1;
//创建命名管道:
//第一个参数:管道的路径名
//第二个参数:操作管道的权限
ret = mkfifo(FIFO_PATHNAME, 0777);
//创建管道成功返回0,失败返回-1
if (-1 == ret)
{
if (EEXIST != errno)
{
perror("mkfifo");
exit(EXIT_FAILURE);
}
}
printf("fifo is ok\n");
//管道创建成功后,可以像普通文件一样操作
//open,read,write,close
int fd = -1;
fd = open(FIFO_PATHNAME, O_RDONLY);
if (-1 == fd)
{
perror("open");
exit(EXIT_FAILURE);
}
while (1)
{
char caBuf[64] = {'\0'};
ret = read(fd, caBuf, sizeof(caBuf));
if (0 == ret)
{
printf("no data to read\n");
sleep(1);
//break;
}
if (ret > 0)
{
printf("%s\n", caBuf);
printf("read %d bytes from fifo\n", ret);
}
}
close(fd);
return 0;
}
运行结果:
test.PNG
mmap.c
#include <sys/mman.h> //mmap
#include <stdio.h>
#include <string.h>
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*close()*/
#include <unistd.h>
#include <stdlib.h> //exit()
int main(void)
{
int fd = -1;
fd = open("test", O_RDWR);
if (-1 == fd)
{
perror("open");
exit(-1);
}
void *pRet = NULL;
pRet = mmap(NULL, 32, PROT_WRITE | PROT_READ, MAP_SHARED
, fd, 0);
if ((void *)-1 == pRet)
{
perror("mmap");
exit(-1);
}
//memcpy();
sprintf((char *)pRet, "%s %d %.2f\n"
, "laoshaotongchi", 1024, 3.14);
munmap(pRet, 32);
return 0;
}
read.c
#include <sys/mman.h> //mmap
#include <stdio.h>
#include <string.h>
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*close()*/
#include <unistd.h>
#include <stdlib.h> //exit()
int main(void)
{
int fd = -1;
fd = open("test", O_RDWR);
if (-1 == fd)
{
perror("open");
exit(-1);
}
void *pRet = NULL;
pRet = mmap(NULL, 32, PROT_WRITE | PROT_READ, MAP_SHARED
, fd, 0);
if ((void *)-1 == pRet)
{
perror("mmap");
exit(-1);
}
//memcpy();
char caBuf[32] = {'\0'};
int iData = 0;
float fData = 0;
sscanf(pRet, "%s%d%f", caBuf, &iData, &fData);
printf("%s %d %.2f\n", caBuf, iData, fData);
munmap(pRet, 32);
close(fd);
return 0;
}
运行结果:
mmap.PNG
pipe
pipe1.png pipe2.pngshmget.c
/*shmget()*/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h> //errno
#include <string.h> //perror()
#include <unistd.h>
#include <stdlib.h> //exit()
int main(void)
{
int shmid = -1;
//第一个参数:key_t key,相当于这块共享内存的名字
//第二个参数:这块共享内存的大小
shmid = shmget(0x1204, 1024, IPC_CREAT | S_IRUSR | S_IWUSR);
if (-1 == shmid)
{
perror("shmget");
exit(EXIT_FAILURE);
}
printf("shmget ok: id = %d\n", shmid);
void *pRet = NULL;
pRet = shmat(shmid, NULL, 0);
if ((void *)-1 == pRet)
{
perror("shmat");
exit(EXIT_FAILURE);
}
char *pData = "I want to sleep";
memcpy(pRet, pData, strlen(pData));
shmdt(pRet);
return 0;
}
运行结果:
shmget.PNG
readShm.c
/*shmget()*/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h> //errno
#include <string.h> //perror()
#include <unistd.h>
#include <stdlib.h> //exit()
int main(void)
{
int shmid = -1;
//第一个参数:key_t key,相当于这块共享内存的名字
//第二个参数:这块共享内存的大小
shmid = shmget(0x1204, 1024, IPC_CREAT | S_IRUSR | S_IWUSR);
if (-1 == shmid)
{
perror("shmget");
exit(EXIT_FAILURE);
}
printf("shmget ok: id = %d\n", shmid);
void *pRet = NULL;
//将共享内存映射到进程空间
//第二个参数:表示映射到进程空间哪个地方
// NULL: 表示让系统自动映射到进程空间合适的地方去
//第三个参数:指定对共享内存的操作权限
// SHM_RDONLY:只读
// 0:读写
// 没有只写
pRet = shmat(shmid, NULL, SHM_RDONLY);
if ((void *)-1 == pRet)
{
perror("shmat");
exit(EXIT_FAILURE);
}
char caBuf[32] = {'\0'};
memset(caBuf, '\0', sizeof(caBuf));
//数据读取之后,仍然保留在共享内存里面
//直到下一次写数据的时候被覆盖
memcpy(caBuf, pRet, sizeof(caBuf));
printf("%s\n", caBuf);
struct shmid_ds shmInfo;
//控制共享内存
//IPC_STAT:获得共享内存的信息,将信息放在shmInfo中
shmctl(shmid, IPC_STAT, &shmInfo);
printf("shm size = %d\n", shmInfo.shm_segsz);
shmctl(shmid, IPC_RMID, NULL);
//shmdt(pRet);
return 0;
}
alarm.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
//在指定的秒数之后,给本进程发送一个SIGALRM信号
//该信号的默认处理是结束进程
//如果参数seconds为0,
//则之前设置的闹钟会被取消,并将剩下的时间返回
//返回值:如果调用此alarm()前,
//进程已经设置了闹钟时间,
//则返回上一个闹钟时间的剩余时间,否则返回0。
//出错返回-1
alarm(5);
while (1)
{
printf("hahahahahahaha...\n");
sleep(1);
}
return 0;
}
运行结果:
alarm.PNG
kill.c
/*kill()*/
#include <sys/types.h>
#include <signal.h>
/*fork()*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
pid_t pid = -1;
pid = fork();
if (pid > 0) //parent
{
while (1)
{
printf("I am parent, waiting child to kill me\n");
sleep(1);
}
}
else if (0 == pid) //child
{
int i = 5;
while (1)
{
if (0 == i)
{
printf("i kill parent\n");
//向指定的进程发送信号
kill(getppid(), SIGKILL);//getppid()获得父进程的进程号
break;
}
else
{
printf("still has %d second to kill parent\n", i);
sleep(1);
}
i--;
}
}
else if (-1 == pid) //error
{
perror("fork");
exit(-1);
}
return 0;
}
运行结果:
kill.PNG
raise.c
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int i = 5;
while (1)
{
if (0 == i)
{
raise(SIGKILL);
}
printf("aaaaaa\n");
i--;
sleep(1);
}
return 0;
}
运行结果:
raise.PNGsignal.c
#include <signal.h> //signal()
#include <stdio.h>
#include <string.h>
typedef void (*sighandler_t)(int);
//使用sigHandle函数处理信号时
//会将信号的值赋给形参sig
void sigHandle(int sig)
{
if (SIGALRM == sig)
{
printf("catched sigalrm\n");
}
else if (SIGINT == sig)
{
printf("catched sigint\n");
}
//SIGINT //ctrl + c
}
int main(void)
{
//The signals SIGKILL and SIGSTOP cannot be caught or ignored.
sighandler_t ret;
//指定信号的处理方式
//第一个参数:需要特殊处理的信号
//第二个参数:信号的处理方式
ret = signal(SIGALRM, sigHandle);
if (SIG_ERR == ret)
{
printf("signal failed\n");
return -1;
}
// ret = signal(SIGINT, sigHandle);
//SIG_DFL:使用该信号的默认处理动作来处理该信号
// ret = signal(SIGINT, SIG_DFL);
//SIG_IGN:忽略该信号
ret = signal(SIGINT, SIG_IGN);
if (SIG_ERR == ret)
{
printf("signal failed\n");
return -1;
}
alarm(3);
while(1)
{}
return 0;
}
运行结果:
signal.PNG
网友评论