day05

作者: 萌面大叔2 | 来源:发表于2017-02-15 13:06 被阅读0次

通过无名管道,让两个子进程间完成相互通信工作

#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.PNG

test.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.png

shmget.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.PNG

signal.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

相关文章

网友评论

      本文标题:day05

      本文链接:https://www.haomeiwen.com/subject/nlklmttx.html