0

我理解多线程单元的概念,即如果一个对象是由一个线程创建的,那么它可以在所有其他线程中使用。

我读过每个进程有一个多线程单元。在 ASP.NET 中,通常有一个用于 IIS 的 W3WP.exe 进程。因此,IIS 如何区分一个用户在一个会话或一个应用程序中创建的对象和另一个用户在另一个会话中创建的对象?我假设使用了 Session 对象和 Application 对象,但我不清楚,想知道是否还有其他机制。

工作线程和 I/O 线程如何适应这个概念?即,如果我有一个程序不创建自己的任何线程(使用 System.Threading.Thread)并且不使用除 .NET 框架的那些部分之外的任何第三方库,那么我假设所有代码在该程序是线程安全的吗?

4

2 回答 2

0

当您处理标准 FORMS 或 CMD Line 应用程序时,假设您不创建任何显式线程并且不使用任何暗示单独线程(如后台工作程序)的组件,那么您将在主应用程序线程上操作所有正常输入的用户代码. 系统将创建其他线程来执行各种操作以支持您的应用程序,但出于所有密集目的,您可以认为它是线程安全的。还有其他线程将是 otehr 组件的一部分,并且应该已经以安全的方式进行编码,以便在没有任何冲突或跨线程问题的情况下进行交互。

正如您所指出的,在 ASP.NET 中这是不同的。除了特定页面之外,IIS 并不真正关心您创建的对象。您的主线程是针对给定请求的,实际上主要对象是“页面”,页面中存储的任何内容都位于这种没有冲突可以真正解决的隐蔽空间中。也是会话对象,这是特定于页面的,并且尽可能与特定请求隔离,因此是安全的。从来没有一个 Page 或 Session 对象暴露给另一个,但是这些页面都在同一个应用程序中,并且从技术上讲可以相互看到(除非你做了一些非常奇怪的编码,这肯定会非常非常糟糕)。

在更大程度上变得不安全的是应用程序对象。如果您将对象存储在应用程序空间中并在多个页面请求中使用它,您需要确保您对对象所做的任何事情都不会与可以在并行请求中处理的另一个请求发生冲突。这方面的一个例子可以是在应用程序空间中存储项目的静态数据表。但是,如果您必须采用一种安全的方法来处理它,我通常不会这样做,那就是使用同步对象来不允许来自一个请求/线程的代码与该对象重叠。另请注意,应用程序对象/空间实际上与 VB.Net 中的公共模块空间相同,我使用一个模块来显示下面的示例......

示例 (这是非常简化的,而不是我通常在代码中做的事情,它只是为了解释 SYNCLOCK 机制)

Public Module SharedSpace

    ' what object is used as a syncronizer is irrelavent, just needs defined only once at the start of the application.
    Public SyncDT As New Exception("none")

    Public dt As DataTable

End Module

Public Class PageItem
    Inherits System.Web.UI.Page

    Private Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load

        SyncLock SyncDT
' ...
' work with "dt" ONLY inside the synclock space
' SyncLock blocks can be anywhere but they need to be as short as possible.
' Any code running in another page request will STOP trying to enter the SyncLock (for the object specified) 
' and waits until any existing SyncLock on the same object is released by exiting the SyncLock.
' ...
        End SyncLock

    End Sub

End Class

实际上,只要“dt”仅在具有“Synclock SyncDT”的块内访问,它在多个线程之间是安全的。但是,以这种方式在没有 SyncLock 的情况下访问“dt”是不可接受的,因为可能会发生重叠。

.NET 中还有其他线程编组对象,Synclock 是我的首选。

于 2013-04-14T23:50:55.633 回答
0

单线程进程不能保证线程安全。如果一个进程接收到一个信号,并且当访问一些关键数据时进程停止,并且单个处理程序也访问了该关键数据,那么它不是线程安全的。

于 2020-09-24T03:48:31.837 回答