几道简单的例子让你了解LINUX下的进程通信

来源:互联网 发布:游戏程序员招聘 编辑:程序博客网 时间:2024/05/16 14:08

不同进程的空间是相互独立的,但我们可以通过进程间通信在不同进程之间传播或交换信息。

在这篇文章里,主要介绍二种通信手段

一:管道通信

二:信号通信



一:管道通信

管道通信通过在进程外建立一个管道,里面可以写入读出数据。

管道分无名管道和有名管道,有名管道可以在系统里建立一个管道文件。

无名管道的例子:

pipe函数

表头文件 unistd.h

定义函数 int pipe(int fildes[2]);

函数说明 pipe()会建立管道,并将文件描述符由参数filedes数组返回,filedes[0]为管道的读取端,filedes[1]为写入端

返回值:若成功则返回0;失败返回-1


#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
        int a[2];
        char buffer[80];
        pipe(a);                     //数组a为管道,a[0]读,a[1]写
        pid_t ip=fork();         //建立子进程,ip在子进程里值为0,父进程里值为子进程的PID
        if(ip>0)
        {
                sleep(2);
                printf ("this is father process\n");
                char s[]="hello\n";
                write(a[1],s,sizeof(s)); //向管道写入"hello\n"
                printf("write over\n"); //写入结束
                wait(NULL);         //等待子进程结束
        }
        else
        {
                printf("this is children process\n");
                read(a[0],buffer,80); //等待管道写入,然后读取到buffer数组
                printf("read end\n"); //读取结束
                printf("%s",buffer);
        }
        return 0;
}


运行结果:   

  




有名管道例子

            mkfifo函数

表头文件     sys/types.h sys/stat.h

定义函数     int mkfifo(const char *pathname,mode_t mode)

函数说明     mkfifo通过pathname指向的路径创建一个管道文件,文件权限由mode赋予。该文件必须不存在;

返回值        成功则返回0;失败返回-1


#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>

int main()

{
        unlink("/home/17717/piping"); //不管有没有,删除17717目录下的piping文件
        mkfifo("/home/17717/piping",0666); //建立一个piping的管道文件
        char sentence[100]; //一个足够大的字符数组
        pid_t a;
        a=fork(); //建立子进程
        int b;
        if (0==a) //只有子进程才能进去
        {
                b=open("/home/17717/piping",O_WRONLY);//以可写权限打开piping管道,并把文件赋值给实型b
                char c[]="Confidence and Smile";
                write(b,c,sizeof(c)); //将字符串写入管道
                close(b); //关闭管道
        }

        else
        {


                b=open("/home/17717/piping",O_RDONLY);//以可读权限打开piping管道
                read(b,sentence,100); //读取管道内的数,并读取到数组sentence
                printf("%s\n",sentence);
                close(b); //关闭管道
        }
        return 0;
}       

运行结果:





二:信号通信

                    kill 函数

表头文件     sys/types.h    signal.h

定义函数     int kill(pid_t pid , int sig)

函数说明     kill()可以将参数sig代表的信号传送给指定pid进程

    pid>0 (将信号传送给进程号为pid的进程);pid=0(将信号传送给目前进程组相同的所有进程);

    pid=-1(将信号传送给所以进程)              ;pid<0(将信号传送给进程号为pid绝对值的所有进程);

返回值         成功则返回0;失败则返回-1

    sigaction 函数

表头文件     signal.h

定义函数     int sigaction(int signum ;stract sigaction *act,struct sigaction *oldact);

函数说明    signum代表指定信号,当收到该信号时运行处理函数;act oldact代表二个sigaction的结构体指针;oldact为替代信号处理程序

   stract sigaction

  {

    void (*sa_handler)(int);  //信号处理函数

sigset_t sa_mask;           //屏蔽信号集

int sa_flags;                   //取0时,为默认行为,没啥用

void (*sa_reatorer)void   

}

返回值    成功则返回0;失败则返回1


获取信号的进程源代码

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void show_sig(int sig) //当获取到指定信号时
{
        printf("i get the signal,is %d\n",sig);       //当接收到信号时输出这条语句
}
int main()
{       pid_t i=fork(); //利用fork()来看当前进程的pid值
        struct sigaction act,oldact;
        act.sa_handler=show_sig;

sigaction(SIGUSR2,&act,&oldact);  //当受到SIGUSR2信号时,执行show-sig函数

        while(1)
        {
                              sleep(3);
                printf("sleep %d\n",i);
        }
        return 0;
}


发送信号的进程源代码

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
        int i=5;
        while(i)
        {
                printf("%d\n",i);
                i=i-1;
        }
        pid_t a=11086; //根据运行上面程序输出的PID值来赋值
        kill(a,SIGUSR2);     //给指定pid发送SIGUSR2信号
        return 0;
}

运行结果:










原创粉丝点击