Chinaunix首页 | 论坛 | 博客
  • 博客访问: 551763
  • 博文数量: 156
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1183
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-22 11:42
文章分类

全部博文(156)

文章存档

2015年(67)

2014年(89)

分类: 嵌入式

2014-10-30 10:26:28

原文地址:嵌入式,进程通信 作者:一生有你llx

进程通信(IPC)的原因:数据传输,资源共享,通知事件,进程控制

POSIX可移植操作系统接口,IEEE电气和电子工程师协会

linux进程通信方式:管道(pipe)和有名管道(FIFO)

                                信号(signal)

                                消息队列

                                共享内存

                                信号量

                                套接字(socket)

1、管道:单向的,先进先出的,把一个进程的输出和一个进程的输入连接在一起。一个进程的管道尾部写入数据,另一个进程的管道头部读出数据

          无名管道:用于父进程和子进程之间的通信                          

                            int  pipe(int  filedis[2]);产生两个描述文件filedis[0]用于读管道 ,filedis[1]用于写管道

                            关闭管道close(filedis[0]);close(filedis[1])

                           管道通信时先建立管道,然后利用fork建立子进程,子进程会继承父进程所建立的管道



2、信号量

信号量:又名信号灯,主要用途是保护临界资源

二值信号量,只能取0或1。计数信号量,可以取任意非负值

信号量创建和打开:#include                    

                               int  semgey(key_t   key,  int  nsems,  int  smflg)

                               key 由ftok获取        nsems  打开或创建的信号灯集中包含的信号灯数目

                               semflg标识

信号量操作:int semop (int  semid,struct  sembuf *sops,unsigned  nsops)

                     semid  信号量集的ID

                     sops数组,表示要进行的操作

                                  struct  sembuf{

                                             unsigned  short  sem_nem           所取的信号量在集合中的位置,即数组的下标

                                             short  sem_op                             要进行的操作,1释放,-1获取

                                             short  sem_flg                   IPC_NOWAIT  /   IPC_IPDO

                                                                                       不阻塞                程序结束时释放

                                                    }

                     nsops,    表示 sops所指向数组的元素个数

3、消息队列

消息队列,就是一个消息链表,具有特定的格式,进程可以按照一定的规则添加消息,另一个进程则可以读取消息

                 目前主要有两种消息队列,POSIX消息队列和系统V消息队列

系统V消息队列随拟合持续,只有重启内核或者人工删除时,消息队列才会删除

每个消息队列都在系统范围内有一个键值,所以要获得消息的描述字必须先获取键值

键值获取:#include                     #include 

                 key_t  ftok(char  *pathname ,  char  proj)           proj项目名,不为0 即可

消息创建或者打开: #include         #include       #include

                          int  msgget(key_t  key,int  msgflg )  返回消息队列的描述字         key由ftok获取

                         msgflg标识位          IPC_CREAT                  创建新的消息队列

                                                        IPC_EXCL                     与IPC_CREAT一起使用,如果要创建的消息存在,返回错误

                                                        IPC_NOWAIT                消息队列要求无法得到满足时,不阻塞

                         如果没有与key值对应的消息队列,并且msgflg中包含 IPC_CREAT则创建新的消息队列    

                         如果key的参数为IPC_PRIVATE 则创建新的消息队列             

  向消息队列发送消息:int  msgsnd(int  msqid,struct  msgbuf  *msgp,int  msgsz,int  msgflg)

                                     struct  msgbuf{

                                                long  mtype;         消息类型

                                                char  mtext[1];      消息数据收地址

                                                            }                         

接收消息:int  msgrcv(int  msqid,struct  msgbuf *msgp,int  msgsz,long  msgtyp,int  msgflg)

                  从msqid代表的队列中读取一个msgtyp类型的消息,保存在msgp中,消息读取后将被删除

4、共享内存

共享内存:被多个进程共享的一部分物理内存,它访问数据快

共享内存的实现:创建共享内存  int  shmget(key_t  key,int  size,int  shmflg)创建错误返回-1,成功则返回标识符

                                                   key的取值0/PRIVATE,          key取PRIVATE时创建一块新的共享内存

                                                   key取0 时,而shmflg又设置参数PRIVATE,同样创建一块新的共享内存

                                                   size内存的大小                                               

                            映射:int  shmat(int shmid,char  *shmaddr,int  flag)成功则映射到进程中的地址,失败返回-1

                                      shmid时shmget返回的标识符

                                      flag决定映射的方式,通常为0

                           解除映射  int  shmdt(char *shmaddr)
5、信号

常见的信号:SIGHUP                 从终端上发出的结束信号

                     SIGINT                   来自键盘的中断信号ctrl+c

                     SIGKILL                 该信号结束接收信号的进程

                     SIGTERM              kill命令发出的信号

                     SIGCHLD              标识子进程结束或停止的信号

                     SIGSTOP                来自键盘(ctrl+z)或调试程序的停止执行信号

信号处理方式:大多数信号忽略,SIGKILL   SIGSTOP这两个信号不能忽略

                        执行用户希望的动作,调用用户函数

                        执行系统默认动作,大多数情况默认结束进程

发送信号函数#include              #include

                     int  kill(pid_t  pid,int  signo)    可以向自身或者其他进程发送信号

                     int  raise(int   signo)               只能向自身发送信号

alarm函数     #include

                     unsigned    int  alarm(unsigned  int  seconds)         经过seconds秒产生一个发送给自己的信号SIGALRM

                      每个进程只能有一个闹钟时间

pause函数  #include

                 int  pause()      进程等待,直到收到一个信号

信号处理函数signal        #include 

                                      void(*signal(int  signo , void(*func)(int)))(int)

                                     func的值:SIG_IGN     忽略信号

                                                      SIG_DFL    默认方式处理

                                                      信号处理函数名

阅读(635) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~