อ่าน 7 นาที
พื้นที่จัดเก็บข้อมูลเฉพาะเธรด
ใน การเขียนโปรแกรมคอมพิวเตอร์ หน่วยความจำเฉพาะเธรด ( Thread-Local Storage หรือ TLS ) เป็น วิธี การจัดการหน่วยความจำ ที่ใช้ หน่วยความจำ แบบคงที่ หรือแบบทั่วโลกเฉพาะสำหรับ แต่ละ...
พื้นที่จัดเก็บข้อมูลเฉพาะเธรด
ในการเขียนโปรแกรมคอมพิวเตอร์ หน่วยความจำเฉพาะเธรด ( Thread-Local StorageหรือTLS ) เป็น วิธี การจัดการหน่วยความจำที่ใช้หน่วยความจำแบบคงที่หรือแบบทั่วโลกเฉพาะสำหรับ แต่ละ เธรดแนวคิดนี้ช่วยให้สามารถจัดเก็บข้อมูลที่ดูเหมือนจะเป็นข้อมูลทั่วโลกในระบบที่มีเธรดแยกกันได้
ระบบหลายระบบกำหนดข้อจำกัดเกี่ยวกับขนาดของบล็อกหน่วยความจำเฉพาะเธรด ซึ่งมักจะเป็นข้อจำกัดที่ค่อนข้างเข้มงวด ในทางกลับกัน หากระบบสามารถจัดหาตัวแปรเฉพาะเธรดที่มีขนาดเท่ากับที่อยู่หน่วยความจำ (ตัวชี้) ได้อย่างน้อย ก็จะช่วยให้สามารถใช้บล็อกหน่วยความจำที่มีขนาดตามต้องการได้ในลักษณะเฉพาะเธรด โดยการจัดสรรบล็อกหน่วยความจำดังกล่าวแบบไดนามิกและจัดเก็บที่อยู่หน่วยความจำของบล็อกนั้นไว้ในตัวแปรเฉพาะเธรด บนเครื่องRISC ข้อกำหนดการเรียกฟังก์ชันมักจะสงวน รีจิส เตอร์ตัวชี้เธรดไว้สำหรับการใช้งานนี้
การใช้งาน
แม้ว่าโดยทั่วไปแล้วการใช้ตัวแปรส่วนกลางจะไม่เป็นที่นิยมในการเขียนโปรแกรมสมัยใหม่ แต่ระบบปฏิบัติการรุ่นเก่าบางระบบ เช่นUNIXถูกออกแบบมาสำหรับ ฮาร์ดแวร์ แบบโปรเซสเซอร์เดี่ยวและมักใช้ตัวแปรส่วนกลางเพื่อจัดเก็บค่าสำคัญ ตัวอย่างเช่น ตัวแปร `value` ที่errnoใช้โดยฟังก์ชันต่างๆ ในไลบรารี Cบนเครื่องคอมพิวเตอร์สมัยใหม่ ที่มีหลายเธรดอาจแก้ไขerrnoตัวแปรนี้ การเรียกใช้ฟังก์ชันระบบในเธรดหนึ่งอาจเขียนทับค่าที่ตั้งไว้ก่อนหน้านี้โดยการเรียกใช้ฟังก์ชันระบบในเธรดอื่น ซึ่งอาจเกิดขึ้นก่อนที่โค้ดถัดไปในเธรดนั้นจะตรวจสอบเงื่อนไขข้อผิดพลาดได้ วิธีแก้ปัญหาคือการสร้างerrnoตัวแปรที่ดูเหมือนจะเป็นตัวแปรส่วนกลาง แต่จริงๆ แล้วถูกจัดเก็บไว้ในหน่วยความจำเฉพาะเธรด หรือหน่วยความจำเฉพาะเธรด (thread-local storage)
กรณีการใช้งานที่สองคือเธรดหลายตัวรวบรวมข้อมูลลงในตัวแปรส่วนกลาง เพื่อหลีกเลี่ยงสภาวะการแข่งขัน (race condition ) การเข้าถึงตัวแปรส่วนกลางทุกครั้งจะต้องได้รับการป้องกันด้วยmutexแต่ในทางกลับกัน แต่ละเธรดอาจรวบรวมข้อมูลลงในตัวแปรเฉพาะเธรด (thread-local variable) ซึ่งจะช่วยขจัดความเป็นไปได้ของสภาวะการแข่งขัน และไม่จำเป็นต้องใช้การล็อก จากนั้นเธรดก็เพียงแค่ซิงโครไนซ์ข้อมูลที่รวบรวมได้ครั้งสุดท้ายจากตัวแปรเฉพาะเธรดของตนเองไปยังตัวแปรส่วนกลางตัวเดียว
การใช้งาน Windows
ฟังก์ชัน Application Programming Interface (API) TlsAllocสามารถใช้เพื่อรับดัชนีช่อง TLS ที่ยังไม่ได้ใช้งาน จากนั้น ดัชนีช่อง TLSนั้นจะถูกพิจารณาว่า 'ใช้งานแล้ว'
จากนั้นจะใช้ ฟังก์ชัน `read` TlsGetValueและTlsSetValue`write` เพื่ออ่านและเขียนที่อยู่หน่วยความจำไปยังตัวแปรเฉพาะเธรดที่ระบุโดยดัชนีสล็อต TLS ฟังก์ชัน ` read` TlsSetValueจะมีผลต่อตัวแปรเฉพาะในเธรดปัจจุบันเท่านั้นTlsFreeสามารถเรียกใช้ฟังก์ชัน `release` เพื่อปล่อยดัชนีสล็อต TLSได้
แต่ละเธรด จะมีWin32 Thread Information Blockหนึ่งในรายการในบล็อกนี้คือตารางจัดเก็บข้อมูลเฉพาะเธรดสำหรับเธรดนั้น[ 1 ] การเรียกแต่ละครั้งTlsAllocจะส่งคืนดัชนีที่ไม่ซ้ำกันในตารางนี้ แต่ละเธรดสามารถใช้TlsSetValue(index, value)และรับค่าที่ระบุได้อย่างอิสระผ่านทางTlsGetValue(index)เนื่องจากสิ่งเหล่านี้จะตั้งค่าและค้นหารายการในตารางของเธรดเอง
นอกเหนือจากฟังก์ชันตระกูล TlsXxx แล้ว ไฟล์ปฏิบัติการของ Windows ยังสามารถกำหนดส่วน (section) ที่แมปไปยังเพจ (page) ที่แตกต่างกันสำหรับแต่ละเธรดของกระบวนการที่กำลังทำงานอยู่ ซึ่งแตกต่างจากค่า TlsXxx ตรงที่เพจเหล่านี้สามารถมีแอดเดรสที่ถูกต้องและไม่จำกัดได้ อย่างไรก็ตาม แอดเดรสเหล่านี้จะแตกต่างกันสำหรับแต่ละเธรดที่กำลังทำงานอยู่ ดังนั้นจึงไม่ควรส่งไปยังฟังก์ชันแบบอะซิงโครนัส (ซึ่งอาจทำงานในเธรดที่แตกต่างกัน) หรือส่งไปยังโค้ดที่สมมติว่าแอดเดรสเสมือนนั้นไม่ซ้ำกันภายในกระบวนการทั้งหมด ส่วน TLS จะถูกจัดการโดยใช้การแบ่งเพจหน่วยความจำและขนาดของมันจะถูกกำหนดให้เท่ากับขนาดของเพจ (4kB บนเครื่อง x86) ส่วนดังกล่าวสามารถกำหนดได้เฉพาะภายในไฟล์ปฏิบัติการหลักของโปรแกรมเท่านั้นDLLไม่ควรมีส่วนดังกล่าว เนื่องจากจะไม่ได้รับการเริ่มต้นอย่างถูกต้องเมื่อโหลดด้วย LoadLibrary
การใช้งาน Pthreads
ใน API ของ Pthreadsหน่วยความจำเฉพาะของแต่ละเธรดจะถูกกำหนดด้วยคำว่า ข้อมูลเฉพาะเธรด (Thread-specific data)
ฟังก์ชัน ` create` pthread_key_createและ ` pthread_key_deletedelete` ใช้สำหรับสร้างและลบคีย์สำหรับข้อมูลเฉพาะเธรดตามลำดับ ประเภทของคีย์ถูกกำหนดให้เป็นแบบไม่เปิดเผยและเรียกว่า `undefined` pthread_key_tคีย์นี้สามารถมองเห็นได้โดยทุกเธรด ในแต่ละเธรด คีย์สามารถเชื่อมโยงกับข้อมูลเฉพาะเธรดได้ผ่านทาง `link key` และpthread_setspecificสามารถเรียกข้อมูลนั้นกลับมาได้ในภายหลังโดยใช้ ` pthread_getspecificlink key`
นอกจากนี้ ยังpthread_key_createสามารถรับฟังก์ชันตัวทำลาย (destructor) ได้โดยเลือก ซึ่งจะถูกเรียกโดยอัตโนมัติเมื่อเธรดสิ้นสุดการทำงาน หากข้อมูลเฉพาะเธรดไม่ใช่ค่า NULLฟังก์ชันตัวทำลายจะรับค่าที่เกี่ยวข้องกับคีย์เป็นพารามิเตอร์ เพื่อดำเนินการทำความสะอาด (ปิดการเชื่อมต่อ ปลดปล่อยหน่วยความจำ ฯลฯ) แม้ว่าจะระบุฟังก์ชันตัวทำลายแล้ว โปรแกรมก็ยังต้องเรียกฟังก์ชันpthread_key_deleteเพื่อปลดปล่อยข้อมูลเฉพาะเธรดในระดับกระบวนการ (ฟังก์ชันตัวทำลายจะปลดปล่อยเฉพาะข้อมูลที่อยู่ในเธรดนั้นเท่านั้น)
การใช้งานเฉพาะภาษา
นอกจากการพึ่งพาโปรแกรมเมอร์ในการเรียกใช้ฟังก์ชัน API ที่เหมาะสมแล้ว ยังสามารถขยายภาษาโปรแกรมเพื่อรองรับหน่วยความจำเฉพาะเธรด (TLS) ได้อีกด้วย
ซี และ ซี++
ในC11คีย์เวิร์ดนี้_Thread_localใช้สำหรับกำหนดตัวแปรเฉพาะเธรด ส่วนหัว<threads.h>(ถ้ามี) จะกำหนดให้thread_localเป็นคำพ้องความหมายของคีย์เวิร์ดนั้น
ใน C11 <threads.h>ยังมีการกำหนดฟังก์ชันจำนวนหนึ่งสำหรับการเรียก เปลี่ยนแปลง และทำลายพื้นที่จัดเก็บเฉพาะเธรด โดยใช้ชื่อที่ขึ้นต้นด้วยtss_ใน C23 thread_localกลายเป็นคำหลัก[ 2 ]
thread_local int foo = 0 ;C++11แนะนำ คีย์เวิร์ด thread_local[ 3 ]ซึ่งสามารถใช้ได้ในกรณีต่อไปนี้
- ตัวแปรระดับเนมสเปซ (ส่วนกลาง)
- ตัวแปรคงที่ของไฟล์
- ตัวแปรคงที่ของฟังก์ชัน
- ตัวแปรสมาชิกแบบคงที่
นอกจากนั้นแล้ว การใช้งานคอมไพเลอร์ต่างๆ ยังมีวิธีการเฉพาะในการประกาศตัวแปรเฉพาะเธรดอีกด้วย:
- Solaris Studio C/C++, [ 4 ] IBM XL C/C++, [ 5 ] GNU C , [ 6 ] llvm-gcc, [ 7 ] Clang , [ 8 ]และIntel C++ Compiler (ระบบ Linux) [ 9 ]ใช้ไวยากรณ์:
__thread int number;
- Visual C++ , [ 10 ] Intel C/C++ (ระบบ Windows), [ 11 ] C++Builder , Clang, [ 12 ]และ Digital Mars C++ ใช้ไวยากรณ์:
__declspec(thread) int number;
- C++Builder ยังรองรับไวยากรณ์ดังต่อไปนี้:
int __thread number;
ใน Windows เวอร์ชันก่อน Vista และ Server 2008 __declspec(thread)จะทำงานเฉพาะใน DLL เมื่อ DLL เหล่านั้นถูกผูกไว้กับไฟล์ปฏิบัติการ และจะไม่ทำงานสำหรับ DLL ที่โหลดด้วยLoadLibrary() (อาจเกิดข้อผิดพลาดในการป้องกันหรือข้อมูลเสียหาย) [ 10 ]
ภาษาลิสป์ทั่วไปและภาษาถิ่นอื่นๆ
Common Lispมีฟีเจอร์ที่เรียกว่าตัวแปรที่ มีขอบเขตแบบไดนามิก
ตัวแปรไดนามิกมีการผูกข้อมูลซึ่งเป็นส่วนตัวเฉพาะกับการเรียกใช้ฟังก์ชันและฟังก์ชันย่อยทั้งหมดที่ถูกเรียกใช้โดยฟังก์ชันนั้น
แนวคิดเชิงนามธรรมนี้สอดคล้องกับการจัดเก็บข้อมูลเฉพาะเธรดโดยธรรมชาติ และการใช้งานภาษา Lisp ที่รองรับเธรดก็ทำเช่นนั้น ภาษา Lisp ทั่วไปมีตัวแปรไดนามิกมาตรฐานจำนวนมาก ดังนั้นจึงไม่สามารถเพิ่มเธรดลงในการใช้งานภาษาได้อย่างเหมาะสมหากตัวแปรเหล่านั้นไม่มีความหมายเฉพาะเธรดในการผูกไดนามิก
ตัวอย่างเช่น ตัวแปรมาตรฐาน*print-base*จะกำหนดฐานตัวเลขเริ่มต้นที่ใช้ในการพิมพ์จำนวนเต็ม หากตัวแปรนี้ถูกแทนที่ โค้ดจะพิมพ์จำนวนเต็มในฐานตัวเลขอื่นจนกว่าการแทนที่นั้นจะสิ้นสุดลง
;;; ฟังก์ชัน foo และฟังก์ชันย่อยของมันจะพิมพ์;; ในรูปแบบเลขฐานสิบหก: ( let (( *print-base* 16 )) ( foo ))หากฟังก์ชันสามารถทำงานพร้อมกันบนเธรดต่างๆ ได้ การผูกฟังก์ชันนี้จะต้องเป็นเฉพาะเธรดอย่างเหมาะสม มิฉะนั้นแต่ละเธรดจะแย่งกันควบคุมฐานการพิมพ์ส่วนกลาง
ดี
ใน ภาษา Dเวอร์ชัน 2 ตัวแปรแบบ static และ global ทั้งหมดจะเป็น thread-local โดยค่าเริ่มต้น และประกาศด้วยไวยากรณ์ที่คล้ายกับตัวแปร global และ static "ปกติ" ในภาษาอื่นๆ ตัวแปร global ต้องถูกเรียกใช้งานอย่างชัดเจนโดยใช้ คีย์เวิร์ด shared :
int threadLocal ; // นี่คือตัวแปรเฉพาะเธรดshared int global ; // นี่คือตัวแปรส่วนกลางที่ใช้ร่วมกันกับทุกเธรดคีย์เวิร์ดsharedทำงานทั้งในฐานะคลาสการจัดเก็บและในฐานะตัวกำหนดประเภท – ตัวแปร sharedอยู่ภายใต้ข้อจำกัดบางประการที่บังคับใช้ความสมบูรณ์ของข้อมูลแบบคงที่[ 13 ]ในการประกาศตัวแปรส่วนกลางแบบ "คลาสสิก" โดยไม่มีข้อจำกัดเหล่านี้ต้องใช้คีย์เวิร์ด__gshared ที่ไม่ปลอดภัย: [ 14 ]
__gshared int global ; // นี่คือตัวแปรโกลบอลธรรมดาๆชวา
ในJavaตัวแปร thread-local จะถูกใช้งานโดยThreadLocalอ็อบเจ็กต์คลาส [ 15 ] ThreadLocalจะเก็บตัวแปรประเภท T [ 15 ]ซึ่งสามารถเข้าถึงได้ผ่านเมธอด get/set ตัวอย่างเช่น ตัวแปร ThreadLocal ที่เก็บค่า Integer จะมีลักษณะดังนี้:
private static final ThreadLocal < Integer > myThreadLocalInteger = new ThreadLocal < Integer > ();อย่างน้อยสำหรับ Oracle/OpenJDK วิธีนี้ไม่ได้ใช้พื้นที่จัดเก็บข้อมูลเฉพาะเธรดดั้งเดิม แม้ว่าเธรดของระบบปฏิบัติการจะถูกใช้สำหรับแง่มุมอื่นๆ ของการทำงานแบบมัลติเธรดของ Java ก็ตาม แต่แต่ละอ็อบเจ็กต์ Thread จะจัดเก็บแผนที่ (ที่ไม่ปลอดภัยสำหรับเธรด) ของอ็อบเจ็กต์ ThreadLocal ไปยังค่าของมัน (ตรงข้ามกับการที่แต่ละ ThreadLocal มีแผนที่ของอ็อบเจ็กต์ Thread ไปยังค่าและทำให้เกิดภาระด้านประสิทธิภาพ) [ 16 ]
ภาษาโปรแกรม .NET: C# และภาษาอื่นๆ
ใน ภาษา .NET Frameworkเช่นC#ฟิลด์คงที่สามารถทำเครื่องหมายด้วยแอตทริบิวต์ ThreadStatic ได้ : [ 17 ] : 898
คลาสFooBar { [ThreadStatic] private static int _foo ; }ใน .NET Framework 4.0 คลาส System.Threading.ThreadLocal<T>พร้อมใช้งานสำหรับการจัดสรรและการโหลดตัวแปรเฉพาะเธรดแบบเลซี่[ 17 ] : 899
คลาสFooBar { private static System.Threading.ThreadLocal <int> _foo ; }นอกจากนี้ยังมีAPI สำหรับการจัดสรรตัวแปรเฉพาะเธรดแบบไดนามิก [ 17 ] : 899–890
ออบเจ็กต์ปาสคาล
ในObject Pascal ( Delphi ) หรือFree Pascal สามารถใช้คำ สงวน threadvarแทน'var' เพื่อประกาศตัวแปรที่ใช้พื้นที่จัดเก็บข้อมูลเฉพาะเธรดได้
var mydata_process : integer ; threadvar mydata_threadlocal : integer ;ออบเจกทีฟซี
ในCocoa , GNUstepและOpenStepแต่ละNSThreadอ็อบเจ็กต์จะมีพจนานุกรมเฉพาะเธรดที่สามารถเข้าถึงได้ผ่านthreadDictionaryเมธอด ของเธรดนั้น
NSMutableDictionary * dict = [[ NSThread currentThread ] threadDictionary ]; dict [ @"A key" ] = @"Some data" ;เพิร์ล
ในภาษา Perlฟังก์ชันเธรดถูกเพิ่มเข้ามาในช่วงท้ายของการพัฒนาภาษา หลังจากที่มีโค้ดจำนวนมากอยู่ในComprehensive Perl Archive Network (CPAN) แล้ว ดังนั้น โดยค่าเริ่มต้น เธรดใน Perl จะใช้พื้นที่จัดเก็บข้อมูลเฉพาะของตัวเองสำหรับตัวแปรทั้งหมด เพื่อลดผลกระทบของเธรดต่อโค้ดที่ไม่รองรับเธรดที่มีอยู่เดิม ใน Perl สามารถสร้างตัวแปรที่ใช้ร่วมกันระหว่างเธรดได้โดยใช้แอตทริบิวต์:
ใช้เธรด; ใช้เธรดแบบใช้ร่วมกัน;ตัวแปรโลคัลของฉัน; ตัวแปรที่ใช้ร่วมกันของฉัน: ที่ใช้ร่วมกัน;เพียวเบสิก
ในPureBasic ตัวแปรเธรดจะ ถูก ประกาศด้วยคีย์เวิร์ดThreaded
ตัวแปรแบบมีเกลียว
ไพธอน
ในPythonเวอร์ชัน 2.4 หรือใหม่กว่าสามารถใช้ คลาสภายในโมดูลthreading เพื่อสร้างพื้นที่จัดเก็บข้อมูลเฉพาะเธรดได้
import threading mydata = threading.local ( ) mydata.x = 1สามารถสร้างอินสแตนซ์ของ คลาส ท้องถิ่น หลายรายการเพื่อจัดเก็บชุดตัวแปรที่แตกต่างกันได้ [ 18 ]ดังนั้นจึงไม่ใช่ซิงเกิล ตัน
ทับทิม
Rubyสามารถสร้าง/เข้าถึงตัวแปรเฉพาะเธรดได้โดยใช้ เมธอด []=ต่างๆ[]ดังนี้:
เธรดปัจจุบัน[ : user_id ] = 1สนิม
สามารถสร้างตัวแปรเฉพาะเธรดในRust ได้ โดยใช้thread_local!มาโครที่จัดเตรียมไว้ในไลบรารีมาตรฐานของ Rust:
ใช้std :: cell :: RefCell ; ใช้std :: thread ;thread_local! ( static FOO : RefCell < u32 > = RefCell :: new ( 1 ));FOO . with ( | f | { assert_eq! ( * f . borrow (), 1 ); * f . borrow_mut () = 2 ; });// แต่ละเธรดเริ่มต้นด้วยค่าเริ่มต้น 1 แม้ว่าเธรดนี้จะเปลี่ยนสำเนาของค่าเฉพาะเธรดเป็น 2 แล้วก็ตามlet t = thread :: spawn ( move || { FOO.with ( | f | { assert_eq ! ( * f.borrow ( ), 1 ); * f.borrow_mut ( ) = 3 ; } ); }) ;// รอให้เธรดทำงานเสร็จสมบูรณ์และออกจากโปรแกรมเมื่อเกิดข้อผิดพลาดt.join ( ). unwrap ( );// เธรดดั้งเดิมยังคงค่าเดิมคือ 2 แม้ว่าเธรดลูกจะเปลี่ยนค่าเป็น 3 สำหรับเธรดนั้นFOO . with ( | f | { assert_eq! ( * f . borrow (), 2 ); });ดูเพิ่มเติม
- OpenMP — อีกหนึ่งระบบประมวลผลแบบมัลติโปรเซสซิ่งที่ใช้หน่วยความจำร่วมกัน ซึ่งรองรับการจัดเก็บข้อมูลต่อเธรดผ่าน "ข้อกำหนดคุณลักษณะการแบ่งปันข้อมูล" (ดูในหัวข้อ§ข้อกำหนด )
บรรณานุกรม
ลิงก์ภายนอก
- การจัดการไฟล์ ELF สำหรับพื้นที่จัดเก็บข้อมูลเฉพาะเธรด — เอกสารเกี่ยวกับการใช้งานในภาษา CหรือC ++
- เอกสารอ้างอิงเทมเพลตคลาส ACE_TSS< TYPE >
- เอกสารประกอบเทมเพลตคลาส RWTThreadLocal<Type>
- บทความ " ใช้พื้นที่จัดเก็บข้อมูลเฉพาะเธรดเพื่อส่งข้อมูลเฉพาะเธรด " โดยดั๊ก โดเดนส์
- " การจัดเก็บข้อมูลเฉพาะเธรด " โดยลอว์เรนซ์ โครว์ล
- บทความเรื่อง " การแบ่งปันไม่ใช่เรื่องดีเสมอไป " โดยวอลเตอร์ ไบรท์
- การใช้งาน ThreadLocal ในทางปฏิบัติใน Java: http://www.captechconsulting.com/blogs/a-persistence-pattern-using-threadlocal-and-ejb-interceptors
- GCC " [1] "
- สนิม " [2] "
สรุปเนื้อหา
ข้อมูลสำคัญจากบทความ
ข้อมูลสำคัญเกี่ยวกับ พื้นที่จัดเก็บข้อมูลเฉพาะเธรด
ใน การเขียนโปรแกรมคอมพิวเตอร์ หน่วยความจำเฉพาะเธรด ( Thread-Local Storage หรือ TLS ) เป็น วิธี การจัดการหน่วยความจำ ที่ใช้ หน่วยความจำ แบบคงที่ หรือแบบทั่วโลกเฉพาะสำหรับ แต่ละ...
การใช้งาน
แม้ว่าโดยทั่วไปแล้วการใช้ ตัวแปรส่วนกลาง จะไม่เป็นที่นิยมในการเขียนโปรแกรมสมัยใหม่ แต่ระบบปฏิบัติการรุ่นเก่าบางระบบ เช่น UNIX ถูกออกแบบมาสำหรับ ฮาร์ดแวร์ แบบโปรเซสเซอร์เดี่ยว และมักใช้ตัวแปรส่วนกลางเพื่อจัดเก็บค่าสำคัญ ตัวอย่างเช่น ตัวแปร `value` ที่ errno...
การใช้งาน Windows
ฟังก์ชัน Application Programming Interface (API) TlsAlloc สามารถใช้เพื่อรับ ดัชนีช่อง TLS ที่ยังไม่ได้ใช้งาน จากนั้น ดัชนีช่อง TLS นั้นจะถูกพิจารณาว่า 'ใช้งานแล้ว'
การใช้งาน Pthreads
ใน API ของ Pthreads หน่วยความจำเฉพาะของแต่ละเธรดจะถูกกำหนดด้วยคำว่า ข้อมูลเฉพาะเธรด (Thread-specific data)