zoukankan      html  css  js  c++  java
  • 操作系统-进程间通信

    响应和发送消息

    signal函数

    signal(int, fun)

    在程序捕获到一个值的时候,调用fun

    定义函数:int kill(pid_t pid, int sig);
    函数说明:kill()可以用来送参数sig 指定的信号给参数pid 指定的进程。参数pid 有几种情况:
    1、pid>0 将信号传给进程识别码为pid 的进程.
    2、pid=0 将信号传给和目前进程相同进程组的所有进程
    3、pid=-1 将信号广播传送给系统内所有的进程
    4、pid<0 将信号传给进程组识别码为pid 绝对值的所有进程参数 sig 代表的信号编号可参考附录D

    简单来说

      程序会接收到一些信息

      这个信息可以由系统或其他的程序发出 比如ctrl + c 就是给程序发信息了

      然后我通过这个函数可以在响应这个信息(一接到这个信息就调用某个函数 )

    示例程序

    # include<stdio.h>
    # include<signal.h>
    # include<unistd.h>
    
    int wait_mark;
    
    void waiting()
    {
        while(wait_mark!=0);
    }
    void stop()
    {
     wait_mark=0;
    } 
    
    int main()
    {
        int p1, p2;
        signal(SIGINT,stop); //若捕获到GIGINT信号,则执行后面的动作
        while((p1=fork())==-1);//创建第一个进程
        if(p1>0)//如果是父进程
        {
            
            while((p2=fork())==-1);//创建第二个进程
            if(p2>0)//如果是父进程
            {
                wait_mark=1;
                waiting(0);
    
    
                //此时按下ctrl + c, 捕获到信号,程序继续往下执行
                kill(p1,10);
                kill(p2,12);
                wait();
                wait();
                printf("parent process is killed!
    ");
                exit(0);
            }
            else //如果是p2进程
            {
                wait_mark=1;
                signal(12,stop);
                waiting();
                lockf(1,1,0);
                printf("child process 2 is killed by parent!
    ");
                lockf(1,0,0);
                exit(0);
            }
        }
        else
        {
            wait_mark=1;
            signal(10,stop);
             waiting();
            lockf(1,1,0);
            printf("child process 1 is killed by parent!
    ");
            lockf(1,0,0); 
            exit(0);
        }
        return 0;
    }

    lockf(1,1,0)是锁定屏幕输出,不让其他进程可以输出到屏幕,lockf(1,0,0)则是解锁

    在此程序中注释掉也行

    管道的使用

    nfc写的已经很好了,我这里就直接cv一下

     

    简单来说

      就是有一个文件,他在父进程中被创建出来,写在某个地方,文件有两种访问方式

      一种是往文件尾部不断的写,另一种是从文件头部不断的读,读一个删一个

      因为这个是文件IO,所以在读写时要对文件加锁  

    示例代码

    #include <unistd.h>
    #include <signal.h>
    #include <stdio.h>
    int pid1, pid2;
    int main()
    {
        int fd[2];
        char OutPipe[100], InPipe[100];
        pipe(fd);
        while ((pid1 = fork()) == -1);
        if (pid1 == 0)
        {
            lockf(fd[1], 1, 0);
            sprintf(OutPipe," child 1 process is sending message !");
            write(fd[1], OutPipe, 50);
            sleep(5);
            lockf(fd[1], 0, 0);
            exit(0);
        }
        else 
        {
            while ((pid2 = fork()) == -1);
            if (pid2 == 0)
            {
                lockf(fd[1], 1, 0);
                sprintf(OutPipe,"child 2 process is sending message !");
                write(fd[1], OutPipe, 50);
                sleep(5);
                lockf(fd[1], 0, 0);
                exit(0);
            }
            else
            {
                wait(0);
                read(fd[0], InPipe, 50);
                printf("%s
    ", InPipe);
                wait(0);
                read(fd[0], InPipe, 50);
                printf("%s
    ", InPipe);
                exit(0);
            }
        }
        return 0;
    }

     (三)消息的发送与接收实验 

     简单来说

      这个就像端口一样,服务器监听端口,客户端向服务器发送端口

      然后服务器会对端口进行响应

    示例代码:

    server.c

    #include <sys/types.h>
    #include <sys/msg.h>
    #include <sys/ipc.h>
    #define MSGKEY 75
    struct msgform
    {
        long mtype;
        char mtext[1000];
    } msg;
    int msgqid;
    void server()
    {
        msgqid = msgget(MSGKEY, 0777 | IPC_CREAT); /*创建 75#消息队列*/
        do
        {
            msgrcv(msgqid, &msg, 1030, 0, 0); /*接收消息*/
            printf("(server)received
    ");
        } while (msg.mtype != 1);
        msgctl(msgqid, IPC_RMID, 0); /*删除消息队列,归还资源*/
        exit(0);
    }
    main()
    {
        server();
    }

    client.c

    #include <sys/types.h>
    #include <sys/msg.h>
    #include <sys/ipc.h>
    #define MSGKEY 75
    struct msgform
    {
        long mtype;
        char mtext[1000];
    } msg;
    int msgqid;
    void client()
    {
        int i;
        msgqid = msgget(MSGKEY, 0777); /*打开 75#消息队列*/
        for (i = 10; i >= 1; i--)
        {
            msg.mtype = i;
            printf("(client)sent
    ");
            msgsnd(msgqid, &msg, 1024, 0); /*发送消息*/
        }
        exit(0);
    }
    main()
    {
        client();
    }

      

  • 相关阅读:
    SQLSERVER2008数据库增量备份还原方式
    使用VS2003遇到“无法显示进程。没有正确安装调试器。请运行安装程序安装或修复调试器。”的解决方法
    IIS7下配置最大上传附件大小需要注意的事项
    运行常用指令
    跨库查询推荐使用的方法
    获取客户端IP需要注意的一个问题
    如何判断一个表是否建立索引约束等信息的SQL语句
    SQLServer2005重建索引前后对比
    一个鼠标滚轮控制大小的缩放类。
    全兼容的纯CSS级联菜单
  • 原文地址:https://www.cnblogs.com/shensobaolibin/p/10105159.html
Copyright © 2011-2022 走看看