zoukankan      html  css  js  c++  java
  • Linux 进程学习

    1、linux进程间通讯
            继承unix进程间通讯:管道 信号
            AT&T :system V IPC 通讯进程只能在单个计算机 :信号量  消息队列 共享内存
            BSD:形成了基于socket的进程间通讯机制 TCP/IP
    2、管道
            (1)无名管道:父子进程
                     #include <unistd.h>

                     int pipe(int pipefd[2]);
                     创建一个管道
                     fd[0]:读端
                     fd[1]:写端
                    返回值:
                            0:成功
                            -1:失败
                    注意:(1)当管道已经满了 write pipe 会阻塞
                           (2) 当管道为空   read pipe 会阻塞


                           
            (2)有名管道:任何进程之间
            #include <sys/types.h>
            #include <sys/stat.h>
                    int mkfifo(const char *pathname, mode_t mode);
    3、信号
            信号在软件层次上对中断的一种模拟 异步通讯方式
            中断:对cpu上的中断 (硬件)
            信号:对进程的中断 (软件)
            (1)信号的来源
                    (1)程序执行错误 如 内存访问越界
                    (2)其他进程发送
                    (3)通过控制终端发送 ctrl + c;
                    (4)子进程结束向父进程发送信号 SIGCLD
                    (5)定时器SIGALRM
            (2)信号
                    kill -l 查看当前系统所有的信号
            (3)信号处理方式
                    忽略信号:对信号不做任何处理
                    捕捉信号:定义处理函数 当信号发生的时候 执行相应的处理函数  
                    缺省操作:在linux系统中间都规定了默认操作
            (4)信号的发送与捕捉
                     #include <sys/types.h>
                     #include <signal.h>

                    int kill(pid_t pid, int sig);
                            pid:接受信号的进程的PID
                            sig:信号
                    返回值:0:成功
                            -1:出错
                     int raise(int sig);
                     //kill(getpid(),SIGSTOP);
                        给进程本身发送信号

            (5)定时器的信号捕捉       
                    unsigned int alarm(unsigned int seconds);
                    进程定时器
                    定时时间到 发送SIGALRM
                    SIGALRM:默认操作:终止进程
                    返回值:
                            在调用之前 如果已经设置过闹钟 返回上一次的剩余时间
                            否则返回0
                            -1:出错
                    int pause(void);
                    暂停进程
                    当收到信号时 会唤醒进程继续执行
            (6)信号处理
                    #include <signal.h>
                    typedef void (*sighandler_t)(int);

                    sighandler_t signal(int signum, sighandler_t handler);
           
                    参数:
                            signum:信号
                            handler:SIG_IGN:忽略该信号
                                    SIG_DFL:采用默认方式处理信号
                                    自定义的信号处理函数的指针
                    返回值:返回一个指向信号处理函数的地址

                    1)父进程捕捉子进程的信号
                    2)从终端输入文字再次输出到终端,如果3s没有输入就输出提示
                            //SIGALRM
                            alarm()和signal()
    4、信号的阻塞处理       
            (1)通知系统内核停止向进程发送指定的信号       
            (2)内核对进程接收到的相应的信号进行缓存
           (3)当进程解除相应的信号的阻塞

            设置阻塞的原因:
                    (1)正在执行信号处理函数时有其他的信号到来
                    (2)信号处理函数和其他进程对某个共享区域进行读写
                    sigset_t:信号集
              int sigemptyset(sigset_t *set);
              把信号集合清空


              int sigfillset(sigset_t *set);
              把信号集合填满
              int sigaddset(sigset_t *set, int signum);
              把对应的信号加到阻塞信号集合中

              int sigdelset(sigset_t *set, int signum);
              把对应的信号从阻塞信号集合中删除       
              int sigismember(const sigset_t *set, int signum);
              判断信号是否是在阻塞信号集合中
              int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
              //设置阻塞信号集合

              how:设置信号阻塞掩码的方式
                              SIG_BLOCK:阻塞信号集
                            SIG_UNBLOCK:解除信号集
                            SIG_SETMASK:设置阻塞掩码
             oldset:旧的阻塞集合
             int sigpending(sigset_t *set);
             //获取阻塞的信号 未决信号

            int flag = 0;
            int flag = 1;
            while(flag == 0){
              int sigsuspend(const sigset_t *mask);
            }
              //等待信号  
              (1)设置信号掩码并阻塞进程
             (2)收到信号 恢复原来的屏蔽字
              (3)调用进程设置的信号处理函数
             (4)等待信号处理函数返回后 sigsuspend()返回
              原子操作
              pause() -----等待信号(阻塞的信号除外)
    5、消息队列
            (1)消息的列表
                    队列ID
                    消息ID
             (2)创建
                     #include <sys/types.h>
                    #include <sys/ipc.h>
                    #include <sys/msg.h>

                    int msgget(key_t key, int msgflg);
                    key:指定的ID来生成队列ID key:ftok()通过转换文件来获取
                    msgflg:IPC_CREAT:创建新的消息队列
                           IPC_EXCL:存在报错
                           IPC_NOWAIT:非阻塞
                    返回值:返回队列ID
                    #include <sys/types.h>
                    #include <sys/ipc.h>

                        key_t ftok(const char *pathname, int proj_id);
                        功能:获取key
                        pathname:文件名---->inode节点号
                        proj_id:自己指定

                        由inode节点号和proj_id合成

                        65538:0x10002  
                        
                        38:0x26

                       key: 0x2610002


            (4)接收消息
                     ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
                     参数:
                             msqid:消息队列ID ----- msgget()
                            msgp:消息的缓冲区
                            msgsz:消息结构的大小
                            msgtyp:0:接收消息队列中的第一个消息
                                   大于0:接收消息队列中第一个为msgtyp的消息
                                   小于0:接收消息队列中第一个不小于msgtyp的绝对值由最小的消息
                            msgflg:
                                    0:忽略
                                    MSG_NOERROR:接收的消息大于size 则消息就会截短到size字节 不通知消息发送进程
                                    IPC_NOWAIT:没有指定类型的消息 就会返回错误ENOMSG
                    返回值:实际接收的字节数
                            会删除对应的消息
            (5)发送消息
                     int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
                     参数:
                             msqid:消息队列ID ----- msgget()
                            msgp:发送的消息缓冲区
                            struct msgbuf{
                                    long mtype;//消息类型
                                    char mtext[1];//消息内容
                            };
                            msgsz:消息内容的大小
                            msgflg:
                                    IPC_NOWAIT:发送条件不满足的时 就会立即返回

                                    a):队列消息已经满了
                   
            创建2个子进程 父进程负责发送 子进程1:发送类型为1的消息        子进程2:发送消息类型为2的消息
            子进程1接收类型为1的消息
            子进程2接收类型为2的消息

                   
            (5)控制函数
              int msgctl(int msqid, int cmd, struct msqid_ds *buf);

              msqid:消息队列ID
              cmd:
                      IPC_STAT:获取struct msqid_ds结构 保存到buf
                    IPC_SET:设置struct msgqid_ds结构
                    IPC_RMID:删除消息队列
               buf:存储struct msqid_ds结构

              返回值:成功:0(IPC_STAT,IPC_SET,IPC_RMID)
                        失败:-1

  • 相关阅读:
    很简单的在Ubuntu系统下安装字体和切换默认字体的方法
    Qt添加驱动——Qt数据库之添加MySQL驱动插件
    qt 字体的相关问题
    qt configure参数配置介绍
    Qt封装QTcpServer参考资料--QT4中构建多线程的服务器
    Qt封装QTcpServer参考资料--QTcpServer多线程实现
    Qt封装QTcpServer参考资料--QT自带QTcpServer架构分析
    Qt Creator设置多核编译(-j8参数)
    QString::​arg的用法
    《Qt数据类型》--QByteArray,QString,int,hex之间的转化
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/7615923.html
Copyright © 2011-2022 走看看