进程间通讯

进程间通讯方式(IPC)::无名管道       有名管道       信号量          共享内存          消息队列          信号          套接字         多机通讯

1、有名管道::  在文件目录树中创建一个文件标识(管道文件),实际不占据磁盘空间,在内存上进行,应用于任意两个进程之间数据单向链接;在使用时,在内存上开辟一段空间,A传给B,A写B读,读过的数据就被销毁了,不会保存。

     创建:命令方式     mkfifo                函数方式    mkfifo();

     打开:open

     读写数据:read,write

     关闭:close

2、无名管道::相对于有名管道而言,无名管道在使用时产生,不使用后释放,并不会在系统留下任何痕迹。因为没有留下任何标志,所以只能用于父子进程之间。原因:子进程会复制父进程的文件表数组,而且是浅拷贝。

     创建: int  pipe( int  fd[2]);     fd[0]   读       fd[1]    写

     打开: int  pipe( int fd[2]);      fd[0]   读       fd[1]    写

     读:  read(fd[0],buff,size);

     写: close(fd[1],buff,size);

     关闭:close(fd[1]);   close(fd[0]);

   注意:管道都是半双工通信,而无名管道创建后,父进程在fork产生子进程后,两个进程分别有一对读写,所以要在父子进程分别关闭。

   fd[0]/fd[1] 都是文件描述符,      无名管道创建:int  fd[2];       pipe(fd);

3、信号量::

    计数器,记录资源同一时间能被进程使用(进程在使用时,进行减一操作,用完后加一)

    临界资源,同一时刻只能被一个进程访问的资源。

    临界区,访问临界资源的代码区域。

    原子操作,任何情况下都不能被打断的操作(不可分割的操作)。

    内核对象,用于对进程间通讯时,多进程能够访问同一资源的记录。

    信号量的作用,进程间同步控制。

    信号量的操作:

                  创建或获取:如果是创建,必须初始化;如果获取,则不能初始化。

                  减一操作:p操作

                  加一操作:v操作

                  删除

    函数:   int  semget((key_t)  key, int nsems, int flag);//获取信号量ID

                  int  semctl(int semid, int senum, int cmd,/*union semun arg*/);//信号量操作,使用信号量

                  int  semop(int semid, struct sembuf* buff, int length);//设置pv操作,自动执行信号量集合上的操作数组,原子操作

   函数封装:

int semid = 0;
void seminit()
{
    semid = semget((key_t)1234,1,0666);//创建信号量
    if(semid == -1)
    {
        semid = semget((key_t)1234,1,0666|IPC_CREAT);
        if(semid == -1)
            {
                perror("");
                exit(0);
            }
            union semun v;
            v.val = 0;//val==0; a和b为服务关系
                      //val==1; a和b为竞争关系
            semctl(semid,0,SETVAL,v);//将semid设置成v操作
        }
}
void sem_p()
{
    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = -1;//减一操作
    buf.semflag = SEM_UNDO;//使操作系统跟踪信号,并在进程没有释放该信号量而终止,操作系统释放信号量
    semop(semid,&buf,1);
}
void sem_v()
{
    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = 1;
    buf.sem_flg = SEM_UNDO;
    semop(semid,&buf,1);
}
void sem_del()
{
    semctl(semid,0,IPC_RMID,NULL);//IPC_RMID删除一个不需要的信号量标识符
}

4、信号::是一种比较复杂的通信方式,用于通知接收某个事件已经发生。

5、消息队列::

     消息:数据+类型

     队列:数据结构,先进先出

     消息队列:是一种临时存储消息的队列,完成进程间数据传递,而是有优先级的队列。

     特点:与信号量对比:都以内核为对象来确保多进程访问同一个消息队列,信号量进行进程同步控制,消息队列发送实际数据,

                与管道相比:管道发送的数据没有类型,读取数据端无差别,从管道中按照数据的前后顺序,消息队列数据有类型,读端可以根据数据类型读取特定数据。

6、共享内存:由内核对象来管理共享的区域内存。

      特点:共享内存是最快的一种IPC,在各个进程都有指针直接指向开辟的内存区域,访问时当本进程中的一个内存控制直接操作。

     注意:共享内存是两个以上的进程能够操作的一块物理空间的内存区域,所以共享区域就成了临界资源,所以对于共享区域的访问必须做同步控制。

7、套接字通讯::套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。


  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值