Process Vs Thread:使用示例c#寻找最佳解释

时间:2015-05-08 11:21:32

标签: multithreading process

道歉在这里发布了上述问题,因为我在这里读了几个相同类型的帖子,但事情还不清楚。

我们知道Both processes and threads are independent sequences of execution. The typical difference is that threads (of the same process) run in a shared memory space, while processes run in separate memory spaces.(引自this回答)

上述说明不足以形象化实际情况。如果有人解释什么是带有示例的流程以及它与带有示例的线程有何不同,那将会更好。

假设我开始了MS痛苦或任何会计程序。我们可以说会计程序是过程吗?我觉得不是。会计应用程序可能有多个进程,每个进程可以启动多个线程。

我希望可视化在运行任何应用程序时可以将哪个区域称为进程。所以请解释并指导我以更好的可视化为例,并解释进程和线程是如何不同的。感谢

1 个答案:

答案 0 :(得分:0)

  

假设我开始了MS痛苦或任何会计程序。我们可以说会计程序是过程吗?

是。或者更确切地说,当前正在运行的实例是。

  我猜不是。会计应用程序可能有多个进程,每个进程可以启动多个线程。

流程可能会启动另一个流程,但相对常见的是窗口化软件。

该过程是给定的可执行文件;窗口化应用程序,控制台应用程序和后台应用程序都将涉及正在运行的进程。

进程是指应用程序运行的空间。使用像NotePad这样的简单过程,如果打开两次以便打开两个NotePad窗口,则会有两个NotePad进程。 (对于更复杂的过程也是如此,但请注意,有些人会做自己的工作以保持一致,所以例如,如果你打开Firefox并再次运行Firefox,那么将会短暂地有两个Firefox进程,但第二个会告诉你第一个在退出之前打开一个新窗口,并且进程数返回到一个;有一个进程使得该应用程序内的通信更简单,原因我们现在可以了。)

现在每个进程必须至少有一个线程。该线程包含有关它正在尝试做什么的信息(通常在堆栈中,尽管这当然不是唯一可行的方法)。考虑一下这个简单的C#程序:

static int DoAdd(int a, int b)
{
    return a + b;
}
void Main()
{
    int x = 2;
    int y = 3;
    int z = DoAdd(x, y);
    Console.WriteLine(z);
}

通过这个简单的程序,第2和第3个程序存储在堆栈中的位置(与标签xy对应)。然后将它们再次推入堆栈,线程移动到DoAdd。在DoAdd中,弹出并添加这些,并将结果推送到堆栈。然后将其存储在堆栈中(与标签z对应)。然后再次推送,线程移动到Console.WriteLine。这样做,线程又回到了Main。然后它离开,线程死亡。作为唯一运行其死亡的前景线程导致该过程也结束。

(我在这里进行了简化,我认为现在不需要挑选所有这些简化;我只是提出一个合理的心理模型)。

可以有多个帖子。例如:

static int DoAdd(int a, int b)
{
    return a + b;
}
static void PrintTwoMore(object num)
{
    Thread.Sleep(new Random().Next(0, 500));
    Console.WriteLine(DoAdd(2, (int)num));
}
void Main()
{
    for(int i = 0; i != 10; ++i)
        new Thread(PrintTwoMore).Start(i);
}

这里第一个线程创建了十个线程。这些中的每一个暂停一段不同的时间(只是为了证明它们是独立的),然后对第一个例子的唯一线程执行类似的任务。

第一个线程在创建第10个新线程并设置它时死亡。要运行的这10个线程中的最后一个将是最后一个前台线程,因此当它死亡时,该过程也是如此。

这些线程中的每一个都可以“看到”相同的方法,并且可以“看到”存储在应用程序中的任何数据,尽管对于我们现在不会进入的彼此标记的可能性存在限制。 / p>

流程也可以启动新流程并与之通信。这在命令行程序中很常见,但在窗口程序中却不那么常见。对于Windowed程序,它在* nix上比在Windows上更常见。

这样做的一个例子是Geany进行目录内查找操作。 Geany没有自己的find-in-directory功能,而是运行程序grep然后解释结果。所以我们从一个进程(Geany)开始,运行自己的线程,然后其中一个线程导致grep程序运行,这意味着我们还有一个grep进程运行其线程。 Geany的线程和grep的线程无法像在同一进程中的线程那样容易地相互通信,但是当grep输出结果时,Geany中的线程可以读取该输出并使用它来显示这些结果。