zoukankan      html  css  js  c++  java
  • Windows和Linux进程与线程的区别

    对于windows来说,进程和线程的概念都是有着明确定义的,进程的概念对应于一个程序的运行实例(instance),而线程则是程序代码执行的最小单元。也就是说windows对于进程和线程的定义是与经典OS课程中所教授的进程、线程概念相一致的。

    提供API,CreateThread()用于建立一个新的线程,传递线程函数的入口地址和调用参数给新建的线程,然后新线程就开始执行了。

    windows下,一个典型的线程拥有自己的堆栈、寄存器(包括程序计数器PC,用于指向下一条应该执行的指令在内存中的位置),而代码段、数据段、打开文件这些进程级资源是同一进程内多个线程所共享的。因此同一进程的不同线程可以很方便的通过全局变量(数据段)进行通信,大家都可以对数据段进行读写,这很方便,也被在安全性方面诟病,因为它要求程序员时刻意识到这些数据不是线程独立的。

    对于linux来说,则没有很明确的进程、线程概念。首先linux只有进程而没有线程,然而它的进程又可以表现得像windows下的线程。linux利用fork()和exec函数族来操作多线程。fork()函数可以在进程执行的任何阶段被调用,一旦调用,当前进程就被分叉成两个进程——父进程和子进程,两者拥有相同的代码段和暂时相同的数据段(虽然暂时相同,但从分叉开的时刻就是逻辑上的两个数据段了,之所以说是逻辑上的,是因为这里是“写时复制”机制,也就是,除非万不得已有一个进程对数据段进行了写操作,否则系统不去复制数据段,这样达到了负担最小),两者的区别在于fork()函数返回值,对于子进程来说返回为0,对于父进程来说返回的是子进程id,因此可以通过if(fork()==0)…else…来让父子进程执行不同的代码段,从而实现“分叉”。

    vfork()函数与fork()函数相同,都是系统调用函数,两者的区别是在创建子进程时,fork()函数会复制所有的父进程的资源,包括进程环境、内存资源等,而vfork()函数在创建子进程时不会复制父进程的所有资源,父子进程共享地址空间。这样,在子进程中对虚拟内存空间中变量的修改,实际上是在修改父进程虚拟内存空间中的值。

    注意:在使用vfork()函数时,父进程会被阻塞,需要在子进程中调用_exit()函数退出子进程,不能使用exit()退出函数。

    这是因为在调用exit()函数时,会对输入/输出流进行刷新,释放所占用的资源以及清空缓冲区等;而_exit()函数则不具备刷新缓冲区等操作的功能。

    在exit系统调用中,函数exit()在终止进程时会关闭所有文件,清空缓冲区。因此,如果在fork()函数和vfork()函数中使用exit()函数终止子进程,会清空标准输入/输出流,可能造成临时文件丢失,并且vfork()函数是父子进程共享虚拟内存,如果在子进程中使用exit()函数会严重影响到父进程,所以在使用这两个创建进程的函数时,尽量都不要使用exit()函数终止子进程。

    exec函数族的函数的作用则是启动另一个程序的新进程,然后完全用那个进程来代替自己(代码段被替换,数据段和堆栈被废弃,只保留原有进程id)。这样,如果在fork()之后,在子进程代码段里用exec启动另一个进程,就相当于windows下的CreateThread()的用处了,所以说linux下的进程可以表现得像windows下的线程。

    然而linux下的进程不能像windows下线程那样方便地通信,因为他们没有共享数据段、地址空间等。它们之间的通信是通过所谓IPC(InterProcess Communication)来进行的。具体有管道(无名管道用于父子进程间通信,命名管道可以用于任意两个进程间的通信)、共享内存(一个进程向系统申请一块可以被共享的内存,其它进程通过标识符取得这块内存,并将其连接到自己的地址空间中,效果上类似于windows下的多线程间的共享数据段),信号量,消息队列,套接字。

    参考链接:https://www.cnblogs.com/snailrun/p/5575533.html

  • 相关阅读:
    CF763C Timofey and Remoduling
    CF762E Radio Stations
    CF762D Maximum Path
    CF763B Timofey and Rectangles
    URAL1696 Salary for Robots
    uva10884 Persephone
    LA4273 Post Offices
    SCU3037 Painting the Balls
    poj3375 Network Connection
    Golang zip压缩文件读写操作
  • 原文地址:https://www.cnblogs.com/a3192048/p/12241313.html
Copyright © 2011-2022 走看看