สัญญาณ - การใช้การนับเริ่มต้นคืออะไร?


96

http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim.aspx

ในการสร้างเซมาฟอร์ฉันต้องระบุจำนวนเริ่มต้นและจำนวนสูงสุด MSDN ระบุว่าการนับเริ่มต้นคือ -

จำนวนคำขอเริ่มต้นสำหรับเซมาฟอร์ที่สามารถให้ได้พร้อมกัน

แม้ว่าจะระบุว่าจำนวนสูงสุดคือ

จำนวนคำขอสูงสุดสำหรับเซมาฟอร์ที่สามารถให้ได้พร้อมกัน

ฉันเข้าใจว่าจำนวนสูงสุดคือจำนวนเธรดสูงสุดที่สามารถเข้าถึงทรัพยากรพร้อมกันได้ แต่การใช้การนับเริ่มต้นคืออะไร?

ถ้าฉันสร้างเซมาฟอร์โดยมีจำนวนเริ่มต้นเป็น 0 และจำนวนสูงสุดเป็น 2 เธรดพูลเธรดของฉันจะไม่สามารถเข้าถึงทรัพยากรได้ ถ้าฉันตั้งค่าการนับเริ่มต้นเป็น 1 และจำนวนสูงสุดเป็น 2 เธรดพูลเธรดเท่านั้นที่สามารถเข้าถึงทรัพยากรได้ เฉพาะเมื่อฉันตั้งค่าการนับเริ่มต้นและจำนวนสูงสุดเป็น 2 เธรด 2 เธรดเท่านั้นที่สามารถเข้าถึงทรัพยากรได้พร้อมกัน ดังนั้นฉันจึงสับสนจริงๆเกี่ยวกับความสำคัญของการนับเริ่มต้น?

SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 2); //all threadpool threads wait
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 2);//only one thread has access to the resource at a time
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2, 2);//two threadpool threads can access the resource concurrently

คำตอบ:


83

ใช่เมื่อชุดตัวเลขเริ่มต้นเป็น 0 เธรดทั้งหมดจะรอในขณะที่คุณเพิ่มคุณสมบัติ "CurrentCount" คุณสามารถทำได้ด้วย Release () หรือ Release (Int32)

ปล่อย (... ) - จะเพิ่มตัวนับสัญญาณ

รอ (... ) - จะลดลง

คุณไม่สามารถเพิ่มตัวนับ (คุณสมบัติ "CurrentCount") มากกว่าจำนวนสูงสุดที่คุณตั้งไว้ในการเริ่มต้น

ตัวอย่างเช่น:

SemaphoreSlim^ s = gcnew SemaphoreSlim(0,2); //s->CurrentCount = 0
s->Release(2); //s->CurrentCount = 2
...

s->Wait(); //Ok. s->CurrentCount = 1
...

s->Wait(); //Ok. s->CurrentCount = 0
...

s->Wait(); //Will be blocked until any of the threads calls Release()

1
รหัสของคุณจะนำเสนอได้ดีกว่าในคำตอบแทนที่จะเป็นความคิดเห็น
ChrisF

16
ฮ่า ๆ อาจเป็นครั้งที่ 5 แล้วที่ฉันได้รับคำตอบเดียวกันนี้เพราะเอกสารของผู้สร้างทำให้ฉันสับสนอยู่เสมอว่าจะตั้งค่าใด Cheers
BlueStrat

73

ดังนั้นฉันจึงสับสนจริงๆเกี่ยวกับความสำคัญของการนับเริ่มต้น?

จุดสำคัญอย่างหนึ่งที่อาจช่วยได้คือการWaitลดจำนวนสัญญาณและReleaseเพิ่มขึ้น

initialCountคือจำนวนการเข้าถึงทรัพยากรที่จะได้รับอนุญาตทันที หรือกล่าวอีกนัยหนึ่งก็คือจำนวนครั้งที่Waitสามารถเรียกได้โดยไม่ต้องปิดกั้นทันทีหลังจากที่สัญญาณถูกสร้างอินสแตนซ์

maximumCountคือจำนวนสัญญาณสูงสุดที่สามารถรับได้ เป็นจำนวนครั้งที่Releaseสามารถเรียกได้โดยไม่ต้องโยนข้อยกเว้นโดยถือว่าinitialCountนับเป็นศูนย์ หากinitialCountตั้งค่าเป็นค่าเดียวกับการmaximumCountเรียกReleaseทันทีหลังจากที่สัญญาณถูกสร้างอินสแตนซ์จะทำให้เกิดข้อยกเว้น


20
สิ่งนี้มีประโยชน์มาก! ฉันคิดเกี่ยวกับ Semaphores ย้อนหลังเนื่องจากใน initialCount เป็นจำนวนทรัพยากรที่ถูกบล็อกเริ่มต้นไม่ใช่จำนวนทรัพยากรที่พร้อมใช้งานทันที ขอขอบคุณ.
Philip Tenn

5
@PhilipTenn ฉันยอมรับ - เอกสารไม่ชัดเจนในส่วนนี้
BlueStrat

ฉันเห็นด้วยพวกเขาควรเปลี่ยนชื่อตัวแปรนั้นหรืออัปเดตเอกสาร
IronHide

@Sandbox คุณควรยอมรับ IMO คำตอบนี้เนื่องจากอธิบายความหมายของinitialCountพารามิเตอร์ได้ดี
Michał Turczyn

9

คุณต้องการเข้าถึงทรัพยากรพร้อมกันกี่เธรด ตั้งค่าการนับเริ่มต้นของคุณเป็นจำนวนนั้น หากจำนวนนั้นจะไม่เพิ่มขึ้นตลอดอายุของโปรแกรมให้ตั้งค่าจำนวนสูงสุดของคุณเป็นจำนวนนั้นด้วย ด้วยวิธีนี้หากคุณมีข้อผิดพลาดในการเขียนโปรแกรมในการปล่อยทรัพยากรโปรแกรมของคุณจะหยุดทำงานและแจ้งให้คุณทราบ

(มีตัวสร้างสองตัว: ตัวสร้างที่รับเพียงค่าเริ่มต้นและอีกตัวที่รับจำนวนสูงสุดเพิ่มเติมใช้ตัวสร้างใดก็ได้ที่เหมาะสม)


2

หากคุณไม่ต้องการให้เธรดเข้าถึงทรัพยากรของคุณในบางครั้งคุณจะส่งการนับเริ่มต้นเป็น 0 และเมื่อคุณต้องการให้สิทธิ์การเข้าถึงทั้งหมดหลังจากสร้างเซมาฟอร์คุณจะส่งค่าของการนับเริ่มต้นที่เท่ากับจำนวนสูงสุด . ตัวอย่างเช่น:

hSemaphore = CreateSemaphoreA(NULL, 0, MAX_COUNT, NULL) ;

//Do something here
//No threads can access your resource

ReleaseSemaphore(hSemaphore, MAX_COUNT, 0) ;

//All threads can access the resource now

ดังที่ยกมาใน MSDN Documentation- "การใช้ ReleaseSemaphore อีกครั้งอยู่ระหว่างการเริ่มต้นของแอปพลิเคชันแอปพลิเคชันสามารถสร้างเซมาฟอร์โดยมีการนับเริ่มต้นเป็นศูนย์สิ่งนี้ตั้งค่าสถานะของสัญญาณเป็นแบบไม่มีสัญญาณและบล็อกเธรดทั้งหมดไม่ให้เข้าถึงทรัพยากรที่มีการป้องกันเมื่อแอปพลิเคชัน เสร็จสิ้นการเริ่มต้นใช้ ReleaseSemaphore เพื่อเพิ่มจำนวนให้เป็นค่าสูงสุดเพื่อให้สามารถเข้าถึงทรัพยากรที่ได้รับการป้องกันได้ตามปกติ "


ขออภัยฉันให้ตัวอย่างใน C ++ แม้ว่าจะสามารถคลายข้อสงสัยได้
Abhineet

1

ด้วยวิธีนี้เมื่อเธรดปัจจุบันสร้างเซมาฟอร์ก็สามารถอ้างสิทธิ์ทรัพยากรบางอย่างได้ตั้งแต่เริ่มต้น


ดังนั้นคุณหมายถึงเมื่อฉันต้องการให้เธรดผู้ปฏิบัติงานสองคนเข้าถึงทรัพยากรฉันควรเปลี่ยนการนับเริ่มต้นหรือไม่
Sandbox

ไม่ใช่เป็นเธรดปัจจุบันที่อ้างว่ามีการนับ หากคุณไม่ต้องการให้เธรดปัจจุบันอ้างสิทธิ์การเข้าถึงผ่าน 0 หรือใช้โอเวอร์โหลดด้วยพารามิเตอร์เดียว
Erno

-1

semaphores สามารถนำมาใช้เพื่อปกป้องสระว่ายน้ำของทรัพยากร เราใช้แหล่งทรัพยากรเพื่อนำสิ่งที่มีราคาแพงมาใช้ซ้ำเช่นการเชื่อมต่อฐานข้อมูล

การนับเริ่มต้นจึงหมายถึงจำนวนทรัพยากรที่มีอยู่ในพูลเมื่อเริ่มต้นกระบวนการ เมื่อคุณอ่านinitialCountรหัสในคุณควรคิดในแง่ของความพยายามล่วงหน้าในการสร้างแหล่งข้อมูลนี้

ฉันสับสนจริงๆเกี่ยวกับความสำคัญของการนับเริ่มต้น?

Initial count = Upfront cost

ดังนั้นขึ้นอยู่กับโปรไฟล์การใช้งานแอปพลิเคชันของคุณค่านี้อาจมีผลอย่างมากต่อประสิทธิภาพของแอปพลิเคชันของคุณ ไม่ใช่แค่ตัวเลขตามอำเภอใจเท่านั้น

คุณควรคิดอย่างรอบคอบเกี่ยวกับสิ่งที่คุณสร้างราคาแพงแค่ไหนในการสร้างและจำนวนที่คุณต้องการทันที คุณควรสามารถสร้างกราฟค่าที่เหมาะสมที่สุดสำหรับพารามิเตอร์นี้ได้อย่างแท้จริงและควรคิดเกี่ยวกับการกำหนดค่าเพื่อให้คุณสามารถปรับประสิทธิภาพของกระบวนการให้เข้ากับเวลาที่ดำเนินการได้


-2

ตามที่MSDNอธิบายไว้ในส่วนหมายเหตุ:

ถ้า initialCount น้อยกว่า maximumCount ผลจะเหมือนกับว่าเธรดปัจจุบันมีการเรียก WaitOne (maximumCount ลบ initialCount) ครั้ง หากคุณไม่ต้องการจองรายการใด ๆ สำหรับเธรดที่สร้างเซมาฟอร์ให้ใช้หมายเลขเดียวกันสำหรับ maximumCount และ initialCount

ดังนั้นหากการนับเริ่มต้นคือ 0 และสูงสุดคือ 2 เท่ากับว่า WaitOne ถูกเรียกสองครั้งโดยเธรดหลักดังนั้นเราจึงถึงขีดความสามารถ (จำนวนเซมาฟอร์คือ 0 ในขณะนี้) และไม่มีเธรดใดสามารถเข้าสู่เซมาฟอร์ได้ ในทำนองเดียวกันถ้าการนับเริ่มต้นคือ 1 และสูงสุดคือ 2 WaitOnce ถูกเรียกหนึ่งครั้งและมีเพียงเธรดเดียวเท่านั้นที่สามารถป้อนก่อนที่เราจะถึงขีดความสามารถอีกครั้งและต่อ ๆ ไป

หากใช้ 0 สำหรับการนับเริ่มต้นเราสามารถเรียก Release (2) ได้เสมอเพื่อเพิ่มจำนวนเซมาฟอร์ให้สูงสุดเพื่อให้จำนวนเธรดสูงสุดในการรับทรัพยากร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.