ฟังก์ชั่นที่ยอมรับค่าบางอย่างและส่งคืนค่าอื่นและไม่รบกวนสิ่งใดนอกฟังก์ชั่นไม่มีผลข้างเคียงดังนั้นจึงปลอดภัยต่อเธรด หากคุณต้องการพิจารณาสิ่งต่าง ๆ เช่นวิธีการทำงานของฟังก์ชั่นที่มีผลต่อการใช้พลังงานนั่นเป็นปัญหาที่แตกต่างกัน
ฉันสมมติว่าคุณกำลังอ้างถึงเครื่องทัวริงที่สมบูรณ์ซึ่งกำลังดำเนินการภาษาการเขียนโปรแกรมที่กำหนดไว้อย่างดีบางอย่างที่รายละเอียดการใช้งานไม่เกี่ยวข้อง กล่าวอีกนัยหนึ่งมันไม่สำคัญว่ากองกำลังทำอะไรถ้าฟังก์ชั่นที่ฉันเขียนด้วยภาษาโปรแกรมที่ฉันเลือกสามารถรับประกันการเปลี่ยนไม่ได้ภายในขอบเขตของภาษา ฉันไม่คิดเกี่ยวกับสแต็คเมื่อฉันเขียนโปรแกรมในภาษาระดับสูงและไม่ควรทำ
เพื่อแสดงให้เห็นถึงวิธีการทำงานนี้ฉันจะเสนอตัวอย่างง่ายๆใน C # เพื่อให้ตัวอย่างเหล่านี้เป็นจริงเราต้องตั้งสมมติฐานสองสามข้อ ครั้งแรกที่คอมไพเลอร์เป็นไปตามข้อกำหนด C # โดยไม่มีข้อผิดพลาดและที่สองว่ามันสร้างโปรแกรมที่ถูกต้อง
สมมติว่าฉันต้องการฟังก์ชั่นง่าย ๆ ที่ยอมรับการรวบรวมสตริงและส่งคืนสตริงที่เป็นการรวมกันของสตริงทั้งหมดในการรวบรวมที่คั่นด้วยเครื่องหมายจุลภาค การติดตั้งที่ง่ายและไร้เดียงสาใน C # อาจมีลักษณะเช่นนี้:
public string ConcatenateWithCommas(ImmutableList<string> list)
{
string result = string.Empty;
bool isFirst = false;
foreach (string s in list)
{
if (isFirst)
result += s;
else
result += ", " + s;
}
return result;
}
ตัวอย่างนี้ไม่สามารถเปลี่ยนแปลงได้เบื้องต้น ฉันจะรู้ได้อย่างไร เพราะstring
วัตถุนั้นไม่เปลี่ยนรูป อย่างไรก็ตามการใช้งานไม่เหมาะ เนื่องจากresult
ไม่สามารถเปลี่ยนแปลงได้จึงต้องสร้างวัตถุสตริงใหม่ทุกครั้งผ่านการวนซ้ำเพื่อแทนที่วัตถุดั้งเดิมที่result
ชี้ไป สิ่งนี้อาจส่งผลเสียต่อความเร็วและสร้างแรงกดดันให้กับตัวเก็บขยะเนื่องจากต้องทำความสะอาดสายอักขระพิเศษเหล่านั้นทั้งหมด
ตอนนี้สมมติว่าฉันทำสิ่งนี้:
public string ConcatenateWithCommas(ImmutableList<string> list)
{
var result = new StringBuilder();
bool isFirst = false;
foreach (string s in list)
{
if (isFirst)
result.Append(s);
else
result.Append(", " + s);
}
return result.ToString();
}
แจ้งให้ทราบว่าได้ถูกแทนที่ด้วยวัตถุไม่แน่นอนstring
result
StringBuilder
นี้เป็นมากเร็วกว่าตัวอย่างแรกเพราะสตริงใหม่จะไม่ได้สร้างในแต่ละครั้งที่ผ่านห่วง แต่วัตถุ StringBuilder จะเพิ่มอักขระจากแต่ละสตริงลงในชุดของอักขระเท่านั้นและแสดงผลลัพธ์ทั้งหมดในตอนท้าย
ฟังก์ชั่นนี้ไม่เปลี่ยนรูปแม้ว่า StringBuilder จะไม่แน่นอน
ใช่แล้ว. ทำไม? เนื่องจากแต่ละครั้งที่เรียกฟังก์ชันนี้จะมีการสร้าง StringBuilder ใหม่สำหรับการโทรนั้นเท่านั้น ดังนั้นตอนนี้เรามีฟังก์ชั่นแท้ที่ปลอดภัยต่อเธรด แต่มีส่วนประกอบที่ไม่แน่นอน
แต่ถ้าฉันทำสิ่งนี้
public class Concatenate
{
private StringBuilder result = new StringBuilder();
bool isFirst = false;
public string ConcatenateWithCommas(ImmutableList<string> list)
{
foreach (string s in list)
{
if (isFirst)
result.Append(s);
else
result.Append(", " + s);
}
return result.ToString();
}
}
วิธีนี้ปลอดภัยไหม? ไม่มันไม่ใช่ ทำไม? เพราะชั้นเรียนตอนนี้ถือสถานะซึ่งวิธีการของฉันขึ้นอยู่กับ สภาพการแย่งชิงมีอยู่ในวิธีการ: เธรดหนึ่งอาจแก้ไขIsFirst
แต่เธรดอื่นอาจดำเนินการแรกAppend()
ซึ่งในกรณีนี้ฉันมีเครื่องหมายจุลภาคที่จุดเริ่มต้นของสตริงซึ่งไม่ควรจะมี
เหตุใดฉันจึงต้องการทำเช่นนี้ ฉันอาจต้องการให้เธรดสะสมสตริงเป็นของฉันresult
โดยไม่คำนึงถึงลำดับหรือในลำดับที่เธรดเข้ามาบางทีมันเป็นคนตัดไม้ใครจะไปรู้?
อย่างไรก็ตามเพื่อแก้ไขฉันใส่lock
คำสั่งรอบอวัยวะภายในของวิธีการ
public class Concatenate
{
private StringBuilder result = new StringBuilder();
bool isFirst = false;
private static object locker = new object();
public string AppendWithCommas(ImmutableList<string> list)
{
lock (locker)
{
foreach (string s in list)
{
if (isFirst)
result.Append(s);
else
result.Append(", " + s);
}
return result.ToString();
}
}
}
ตอนนี้มันปลอดภัยสำหรับเธรดอีกครั้ง
วิธีเดียวที่วิธีการที่ไม่เปลี่ยนรูปแบบของฉันอาจไม่ปลอดภัยกับเธรดคือถ้าวิธีการรั่วไหลบางส่วนของการใช้งาน เกิดขึ้นได้ไหม? ไม่ใช่ถ้าคอมไพเลอร์ถูกต้องและโปรแกรมนั้นถูกต้อง ฉันจะต้องล็อคด้วยวิธีการดังกล่าวหรือไม่? เลขที่
สำหรับตัวอย่างของวิธีการดำเนินงานที่อาจจะรั่วไหลออกมาในสถานการณ์ที่เห็นพ้องให้ดูที่นี่
but everything has a side effect
- เอ่อไม่มันไม่ได้ ฟังก์ชั่นที่ยอมรับค่าบางอย่างและส่งคืนค่าอื่นและไม่รบกวนสิ่งใดนอกฟังก์ชั่นไม่มีผลข้างเคียงดังนั้นจึงปลอดภัยต่อเธรด ไม่สำคัญว่าคอมพิวเตอร์จะใช้ไฟฟ้า เราสามารถพูดคุยเกี่ยวกับรังสีคอสมิกที่กระทบเซลล์หน่วยความจำได้ด้วยหากคุณต้องการ แต่ขอโต้แย้งกัน หากคุณต้องการพิจารณาสิ่งต่าง ๆ เช่นวิธีการใช้งานฟังก์ชั่นที่มีผลต่อการใช้พลังงานนั่นเป็นปัญหาที่แตกต่างจากการเขียนโปรแกรม threadsafe