首页 > 技术文章 > 操作系统-进程间通信

shensobaolibin 2018-12-11 20:58 原文

响应和发送消息

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!\n");
            exit(0);
        }
        else //如果是p2进程
        {
            wait_mark=1;
            signal(12,stop);
            waiting();
            lockf(1,1,0);
            printf("child process 2 is killed by parent!\n");
            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!\n");
        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\n", InPipe);
            wait(0);
            read(fd[0], InPipe, 50);
            printf("%s\n", 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\n");
    } 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\n");
        msgsnd(msgqid, &msg, 1024, 0); /*发送消息*/
    }
    exit(0);
}
main()
{
    client();
}

 

  

推荐阅读