2010-09-18 61 views
3

爲什麼線程安全在web應用程序中很重要?主塔(Python web框架)使用不是線程安全的全局應用程序變量。這很重要嗎?如果我打算使用多線程,這只是一個問題嗎?或者,這是否意味着一個用戶可能沒有更新狀態,如果另一個用戶......我只是混淆了我自己。這有什麼重要的?線程安全的網絡應用程序 - 爲什麼這很重要?

回答

2

線程錯誤會導致嚴重和微妙的問題。

說你的系統有10個成員。再有一個用戶註冊您的系統,應用程序將他添加到名單中並增加成員數量; 「同時」,另一個用戶退出,應用程序將他從名冊中刪除,並減少成員的數量。

如果您沒有正確地處理線程,您的成員數(應該是10)很容易就是9,10或11,,您將永遠無法重現錯誤

所以要小心。

+0

你的方案是否假設我將在內存中存儲多個請求Web用戶的狀態,以及在數據庫中?如果是這樣,那可能不會是如此巨大的頭痛,因爲我傾向於通過數據庫來處理這種慢而簡單的方式。 – orokusaki 2010-09-18 19:58:43

+0

你可以在主塔上談論這件事嗎? – orokusaki 2010-09-18 20:04:45

+0

我只是在討論抽象中的線程問題。完成(可能是線程安全的)數據庫中的所有工作並不能解決問題。例如,如果您不明智地增加了成員計數 - 從數據庫中讀取計數,增加計數,將計數寫入數據庫 - 您很可能會遇到線程問題。 – Malvolio 2010-09-28 22:15:33

1

您應該關心線程安全。例如,在Java中編寫一個提供某些功能的servlet。容器將部署你的servlet的一個實例,並且當HTTP請求從客戶端到達時,通過不同的TCP連接,每個請求由一個單獨的線程處理,這個線程又將調用你的servlet。因此,您將會從多個線程調用您的servlet。因此,如果它不是線程安全的,則由於線程訪問共享數據的數據損壞,會將錯誤的結果返回給用戶。

+0

@ user384706 - 你碰巧知道Python中servlet的等價物是什麼? WSGI應用程序是基本等效的嗎? – orokusaki 2010-09-18 20:02:24

+1

@orokusaki:我不知道Python,所以我不知道。但通常,所有框架都會指定它們是否線程安全。例如。 struts2指定它們是線程安全的。即對於每個客戶端請求,分配給每個新連接的每個線程都使用實現類的新實例。對於servlet,實例在連接即線程中共享。不是在Python中指定的嗎?如果不是,那麼我認爲假設,線程不安全並同步對共享數據的訪問會更好。只需分析代碼以確保性能良好。 – Cratylus 2010-09-18 20:12:11

1

它確實取決於應用程序框架(在這種情況下我一無所知)以及Web服務器如何處理它。顯然,任何好的網絡服務器都將同時響應多個請求,因此它將使用多個線程進行操作。該Web服務器可能派發到所有這些請求的應用程序代碼的單個實例,或者它可能產生Web應用程序的多個實例,並且從不同時使用給定的實例。

即使應用程序服務器確實使用不同的實例,您的應用程序可能會有一些共享狀態 - 也就是說,包含用戶列表的數據庫。在這種情況下,您需要確保可以從Web應用程序的多個線程/實例安全地訪問狀態。

然後,當然,你可能會在你的應用程序中明確地使用線程。那樣的話,答案顯而易見。

1

您的Web應用程序幾乎總是多線程。即使你可能不明確使用線程。所以,要回答你的問題:這是非常重要的

這是怎麼發生的?通常,Apache(或IIS)將同時處理多個請求,從多個線程多次調用Python程序。所以你需要考慮你的程序在多個線程中同時運行,並採取相應的行動。

+0

但是,我不明白。這對我有什麼影響?狀態存儲在我的數據庫中,爲什麼這很重要?在一個線程中會發生什麼樣的變化可能會導致另一個線程的運行時間變長?這是我沒有得到的。另外,你是否可以在主塔上發言? – orokusaki 2010-09-18 20:00:44

+1

@crokusaki你似乎混淆持久狀態和請求特定狀態。您的數據庫可以處理持久狀態,但無法處理特定於請求的狀態。假設你有一個稱爲郵政編碼的變量,它初始化爲用戶在表單中輸入的郵政編碼。如果這是線程不安全的(即,如果這個變量只有一個實例存儲在多個線程中),那麼有可能你的第二個用戶的郵政編碼會破壞這個變量,在這種情況下,你的整個邏輯會被搞亂。可能將一個用戶的東西交付給另一個用戶! – 2010-09-18 20:14:32

+0

@raja - 好的。所以基本上,我可能有一個Web框架,它接受設置變量並將其應用於框架狀態,而不是將某種線程安全狀態綁定到單個請求。那麼,一個用戶來了,看到另一個用戶的設置的影響? – orokusaki 2010-09-18 20:19:01

1

(這是太長添加註釋到其他精細答案。)

併發問題(讀:對共享狀態的多址接入)是線程問題超集。 (併發性問題)可以很容易地存在於「線程以上」級別,例如進程/服務器級別(上面提到的情況下,全局變量是進程獨有的值,這反過來又會導致視圖/狀態不一致有多個進程)。

必須注意分析數據一致性要求,然後實施軟件以滿足這些要求。我總是在安全方面犯錯,只有在經過認真分析的地方纔能接受。

但是,請注意,CPython只爲Python代碼執行運行一個線程上下文(以獲得真正的併發線程,您需要編寫/使用C擴展),因此,儘管您可以根據預期的數據獲得競爭條件形式,將不會獲得(全部)相同類型的部分寫入方案,並且可能困擾C/C++程序。但是,再一次。在觀點一致的情況下犯錯。

有許多不同的現有的方法訪問全局原子 - 跨線程或進程。使用它們。

相關問題