繁体   English   中英

进程和线程之间的区别

[英]Difference between process and thread

我今天在采访中被问了一个问题。 首先,他们询问如何在线程之间提供同步。 然后他们询问如何在进程之间提供同步,因为我告诉他们,每个进程内的变量都不能与其他进程共享,所以他们让我解释两个进程如何相互通信以及如何在它们之间提供同步,以及在哪里声明共享变量? 现在面试结束了,但我想知道答案,有人能解释一下吗?谢谢。

我认为面试官可能没有使用正确的术语。 进程在自己的空间中运行,并且在单独的答案中提到过,您必须使用特定于操作系统的机制来在进程之间进行通信。 这称为进程间通信的IPC。

使用套接字是一种常见的做法,但根据您的应用程序而言可能非常低效。 但是如果使用纯Java,这可能是唯一的选择,因为套接字是普遍支持的。

共享内存是另一种技术,但这是特定于操作系统的,需要特定于操作系统的调用。 您必须使用类似JNI的东西来访问Java应用程序以访问共享内存服务。 共享内存访问不同步,因此您可能必须使用信号量来同步多个进程之间的访问。

类Unix系统提供多个IPC机制,使用哪个机制取决于应用程序的性质。 共享内存可能是有限的资源,因此它可能不是最好的方法。 谷歌搜索这个主题提供了大量的点击,提供有关技术细节的有用信息。

进程是虚拟内存空间,代码,数据和系统资源的集合。 线程是要在进程内串行执行的代码。 处理器执行线程而不是进程,因此每个应用程序至少有一个进程,并且进程始终至少有一个执行线程,称为主线程。 除主线程外,进程可以有多个线程。 在引入多个执行线程之前,应用程序都设计为在单个执行线程上运行。

当一个线程开始执行时,它会继续执行,直到它被终止或被一个具有更高优先级的线程(通过用户操作或内核的线程调度程序)中断。 每个线程可以运行单独的代码段,或者多个线程可以执行相同的代码段。 执行相同代码块的线程维护单独的堆栈。 进程中的每个线程共享该进程的全局变量和资源。

为了在两个进程之间进行通信,我认为您可以使用ServerSocket和Socket来管理进程同步。 您将绑定到特定端口(获取锁定),如果已绑定进程,则可以连接到套接字(块)并等待服务器套接字关闭。

private static int KNOWN_PORT = 11000;//arbitrary valid port
private ServerSocket socket;
public void acquireProcessLock(){
   socket = new ServetSocket(KNOWN_PORT);
   INetAddress localhostInetAddres = ...
   try{
      socket.bind(localhostInetAddres );
   }catch(IOException failed){
      try{
       Socket socket = new Socket(localhostInetAddres ,KNOWN_PORT);
       socket.getInputStream().read();//block
      }catch(IOException ex){ acquireProcessLock(); } //other process invoked releaseProcessLock()
   }
}
public void releaseProcessLock(){
  socket.close();
}

不确定这是否是实际的最佳方法,但我认为值得考虑。

同步仅适用于线程,它不适用于Java中的进程。 它们之间没有用于跨进程的实用程序,因为进程不共享任何需要同步的状态。 一个进程中的变量与另一个进程中的变量不具有相同的数据

从系统的角度来看,线程由他的“ 状态 ”和“ 指令指针 ”定义。

指令指针( eip )包含要执行的下一条指令的地址。

线程“ 状态 ”可以是: 寄存器 (eax,ebx等), 信号打开文件代码堆栈 ,由此线程管理的数据 (变量,数组等)以及

进程是一组共享其“ 状态 ”的一部分的线程:它可能是代码数据 希望我回答你的问题;)

编辑:进程可以通过IPC进行通信(进程间通信)。 共有3种机制: 共享内存消息队列 我可以使用Semaphors进行进程之间的同步

可以使用互斥锁进行线程同步( pthread_mutex_lock,pthread_mutex_unlock等

最简单的答案是进程意味着正在执行的程序,程序只是函数集合。 其中thread是proccess的一部分,因为所有的线程都是函数。 换句话说,我们可以说一个进程可能有多个线程。 OS总是为进程分配内存,并且该进程的线程之间会分配内存.OS不为线程分配内存。

在一句话中,流程的设计比线程更独立。
他们的主要差异可以在记忆层面描述。 不同的进程彼此之间没有任何共享,从寄存器,库存到堆内存,这使它们在自己的轨道上安全。 但是,通常线程被设计为共享公共堆内存,这为多个进程计算任务提供了更紧密连接的方式。 创建一种更有效的方式来占用计算资源。

例如,如果我使用3个进程进行计算,我必须让它们各自完成它们的工作并在系统级别等待它们的结果,同时,总是占用寄存器和堆栈存储器。 但是,如果我使用3个线程,那么如果线程2幸运地完成了它的工作,因为它计算的结果已经存储到公共堆内存池,我们可以直接杀死它而无需等待其他人传递结果,这个已发布的寄存器和库存内存资源可用于其他目的。

检查Terracotta Cluster或Terracotta的DSO Clustering文档,了解如何解决此问题(字节码操作,维护putfield / getfield级别的Java语言规范的语义等)

处理:

  • 一个过程只不过是一个正在执行的程序。
  • 每个进程都有自己的内存地址空间。
  • 进程用于重量级任务,即基本上是应用程序的执行。
  • 流程之间的沟通成本很高。
  • 从一个进程切换到另一个进程需要一些时间来保存和加载寄存器,内存映射等。
  • 流程是操作系统方法。

主题:

  • 线程是轻量级子过程。
  • 线程共享相同的地址空间。
  • 线程之间的通信成本很低。

注意:每个线程至少需要一个进程。

我想这些进程可以通过第三方进行通信:文件或数据库......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM