• 应用_进程线程


    进程线程


                     进程是资源分配的基本单位, 线程是系统调度的基本单位

    1.进程:

             孤儿进程,守护进程,僵尸进程

       函数:fork ,wait,waitpid,

      进程间通讯(IPC)

      1. 种类:无名管道,有名管道,信号通讯  

                消息队列,共享内存,信号量灯      

                 socket

      2.目的:实现数据共享

      3.  


      无名管道:内核在物理空间开辟的一段共享缓存,无文件名只用于亲缘之间;

         函数:int pipe( int pipefd[2] ) :数组存放读写文件描述符

         特点:

         代码示例:https://www.cnblogs.com/panda-w/p/11049435.html


      有名管道:内核在物理空间开辟的一段共享缓存,已文件形式操作缓存;

        函数:int mkfifo(const char *pathname, mode_t mode) 创建只需要一个进程,另一个进程直接读写

         特点:

         代码示例:https://www.cnblogs.com/panda-w/p/11049430.html


      信号通讯

         kill :   信号发送

         signal :   信号接收

         raaise :   发信号给自己 

         信号一般有以下设定:
                1,捕捉    (收到某个信号,做指定的自定义动作,而不是做默认的)
                2,忽略    (收到某个信号,不做什么动作)
                3,阻塞    (收到某个信号,先做完当前事情,然后在响应信号)
                4,按照默认动作

           注:SIGKILL,SIGSTOP只能按照系统默认动作执行,不能捕捉,阻塞及忽略
      

      kill -l

      前面31个是非实时信号:
                    1,每一个非实时信号对应一个信号名
                    2,每一个非实时信号基本上都会对应一个系统事件
                    3,信号有可能会丢失

      后面的31个是实时信号:
                   1,信号不会丢失
                   2,优先级比非实时信号要高

         特点:唯一异步通信的IPC

         代码示例:https://www.cnblogs.com/panda-w/p/14755580.html


      消息队列:内核在物理空间创建用于存放消息的双向循环链表;

         函数:msgget    :创建获取标识符

            msgsend :通过标识符发送编号内容

            msgrcv    :通过标识符接收编号内容

            msgctl     :通过标识符删除消息队列

        特点:

        代码示例:https://www.cnblogs.com/panda-w/p/11049411.html


      共享内存:内核在物理空间开辟一大段缓存空间,直接使用地址共享读写,实现通信;

         函数:shmget :创建获取共享内存

               shmat  : 挂载(映射建立)

            shmdt  : 卸载(映射取消)

            shmctl  :删除共享内存

         特点:

         代码示例:https://www.cnblogs.com/panda-w/p/11049407.html


      信号量灯:多进程线程共享操作,通过加锁机制资源保护,实现同步与互斥,防止干扰;

         函数:semget :创建获取信号量集合

            semctl  :设置初始值

               semop : P V 操作 

               semctl : 删除信号量集合

        特点: 

        代码示例:https://www.cnblogs.com/panda-w/p/11049402.html


      socket:


    管道通信方式的中间介质是文件

    相对于管道消息队列不用打开和关闭文件

    消息队列可以支持多个进程,多个进程可以读写消息队列,即消息队列可以实现多对多,
    而无名管道只能是点对点。

    消息队列,FIFO,管道的消息传递方式一般为
    1:输入IPC进程
    2:从进程拷贝到内核
    3:从内核拷贝到进程
    4:进程IPC输出
    共享内存只需要
    1:输入共享内存
    2:共享内存输出

    共享内存区是最快的可用IPC形式,内存访问无需借助内核


         特点:

         代码示例:


    2.线程:轻量级进程,CPU调度的最小单位

        函数:pthread_creat 注册线程函数,实现并发运行

           pthread_dtach/self 线程分离,自动回收

           pthread_cannel/exit  粗暴主动,终止线程

           pthread_join      回收资源(阻塞等待次线程回收)

           pthread_cleanup_push/pop 线程退出函数(压栈弹栈必须成对)

         锁:  

           互斥锁初始化方式:静态宏, 动态函数

            1. 静态宏的设置:

               快速静态锁:普通锁,在嵌套锁时会出现死锁

                pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER

               递归锁:可以嵌套上锁

                pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP

               检错锁:在出现嵌套锁时返回一个错误信息,不会死锁

                pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP

               2.   动态函数设置:

                   int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)

                   参一为初始化的锁名称

                参二为锁的属性,对应快速锁,嵌套锁,检错锁。

          锁的操作:加锁、解锁、测试加锁、销毁锁

            1.加锁:不管是哪种类型的锁,都不可能被两个线程

                int pthread_mutex_lock(pthread_mutex_t *mutex)

            2.解锁:对于快速锁,则解除锁定。对于嵌套锁使锁上的技术减一,表示上了两层。

                对于检错锁,如果锁是本线程加的,则解除锁,否则啥也不干

                int pthread_mutex_unlock(pthread_mutex_t *mutex)

            3.测试:使用测试加锁,则不会挂起阻塞。

                 int pthread_mutex_trylock(pthread_mutex_t *mutex) 

            4.销毁: 销毁锁,意味着释放所占用的资源,而且要求锁处于开放状态。

                 int pthread_mutex_destroy(pthread_mutex_t *mutex)

              

         特点:

         代码示例:https://www.cnblogs.com/panda-w/p/11059617.html

     信号量  互斥锁  条件锁   读写锁  自旋锁  递归锁  atomic

     原子操作是指不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch

    <笔记>

    1.进程内部多线程通讯实现数据共享,使用全局变量即可,开销小

    2.线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制,线程之间通信更方便,同一个    进程下,线程共享全局变量,静态变量等数据,

    3.进程有自己独立的地址空间,每启动一个进程,系统都会为其分配地址空间,建立数据表来维护代码段、堆栈段和数据段,线程    没有独立的地址空间,它使用相同的地址空间共享数据;

    4.多进程程序更安全,生命力更强,一个进程死掉不会对另一个进程造成影响(源于有独立的地址空间),

       多线程程序更不易维护,一个线程死掉,整个进程就死掉了(因为共享地址空间);

    5.进程对资源保护要求高,开销大,效率相对较低,线程资源保护要求不高,但开销小,效率高,可频繁切换;

    6. 在计算机系统中,除了内存,数据还会被缓冲存在cpu的寄存器以及各级缓冲中,当访问一个变量时,可能
        直接从寄存器或cpu中获取,不一定到内存中去取,当修改为一个变量时,也可能是先写到缓冲中,稍后才同步更新到内存中
        使用volatile 关键字解决

    7. 进程之间的通信需要以通信的方式(IPC)进行;(但多线程程序处理好同步与互斥是个难点)

    优质博客:

    https://www.zhihu.com/question/307100151/answer/894486042

    https://www.zhihu.com/question/43591043

    https://blog.csdn.net/phoenixcsl/article/details/83957718

    https://blog.csdn.net/baidu_38301645/article/details/109383942?utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control&dist_request_id=1332042.24741.16193446695993955&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control


    命令: 

            ps:查看进程状态   (一个瞬间的进程状态,静态)
            top:“实时查看” ,按q退出    (实时动态显示)
            pstree  树状查看  (可以看出所属子进程)   

    top:Linux的任务管理器·

    PS :静态的进程统计信息

    a:显示当前终端下的所有进程信息,包括其他用户的进程。
    u:使用以用户为主的格式输出进程信息。
    x:显示当前用户在所有终端下的进程。
    -e:显示系统内的所有进程信息。
    -l:使用长(long)格式显示进程信息。
    -f:使用完整的(full)格式显示进程信息。

    ps  aux    (简单列表的形式显示出进程信息):

    USER  :进程用户名
    PID   :进程的ID
    PPID  :父进程ID
    %CPU  :进程占用的CPU百分比
    %MEM :进程占用内存的百分比
    NI   :进程的NICE值,数值大,表示较少占用CPU时间;
    VSZ  :进程使用的虚拟內存量(KB);
    RSS   :进程占用的固定內存量(KB)(驻留中页的数量);
    TTY  :进程在哪个终端上运行(登陸者的終端位置),若与终端无关,显示(?)。若pts/0,表示网络连接主机进程
    WCHAN: 当前进程程是否正在运行,若为-表示正在运行;
    START :进程被触发启动时间;
    TIME : 进程实际使用CPU运行的时间;
    COMMAND:命令的名称和参数;

     STAT:

      D 无法中断的休眠状态(通常 IO 的进程);
      R 正在运行可中在队列中可过行的;
      S 处于休眠状态;
      T 停止或被追踪;
      W 进入内存交换 (从内核2.6开始无效);
      X 死掉的进程 (基本很少見);
      Z 僵尸进程;
      < 优先级高的进程
      N 优先级较低的进程
      L 有些页被锁进内存;
      s 进程的领导者(在它之下有子进程);
      l 多进程的(使用 CLONE_THREAD, 类似 NPTL pthreads);
      + 位于后台的进程组;

     

    进程有5种状态:
      1. 运行(正在运行或在运行队列中等待)
      2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号)
      3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)
      4. 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放)
      5. 停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行)






    kill 进程号(杀死进程)  kill  -9  pid   强制终止进程

    kill -l :(Linux信号列表)

    1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的)

    32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)

    区别:不可靠信号不支持排队,可能会造成信号丢失

       而可靠信号支持排队,不会造成信号丢失 

    消息队列 / 共享内存 / 信号量:

    查看 :ipcs  -q / -m / -s   删除:ipcrm  -q / -m / -s    [-mid] 

    key:key shmid:编号 owner:创建用户 perms:权限 bytes:大小 nattch:连接共享内存的进程数

    status:共享内存的状态


    <笔记>

    1. 程序运行在磁盘,不占系统资源

     进程运行在内存,占用系统资源

    2. fork之前的代码,父子进程都拥有

    3. 进程就是主线程

    4. 管道是半双工通信

    5. 进程线程应用:

       多进程:执行新程序

       多线程:执行多任务

    6. wait 和 waitpid 区别 :

    7. 

    Stay hungry, stay foolish 待续。。。
  • 相关阅读:
    C# 实现 JAVA AES加密解密(转他人)
    转 Java、C#双语版配套AES加解密示例
    开发工具资料
    WebApi返回Json格式
    【转】NuGet.org 无法访问的解决方法
    使用Senparc.Weixin.WxOpen开发高可用的微信小程序
    WebApi资料
    WinForm资料
    Winform开发框架之终极应用
    Winform开发中另一种样式的OutLookBar工具条
  • 原文地址:https://www.cnblogs.com/panda-w/p/10992334.html
Copyright © 2020-2023  润新知