เมื่อคุณประกาศตัวแปรthread_local
แต่ละเธรดจะมีสำเนาของตัวเอง เมื่อคุณอ้างถึงตามชื่อระบบจะใช้สำเนาที่เกี่ยวข้องกับเธรดปัจจุบัน เช่น
thread_local int i=0;
void f(int newval){
i=newval;
}
void g(){
std::cout<<i;
}
void threadfunc(int id){
f(id);
++i;
g();
}
int main(){
i=9;
std::thread t1(threadfunc,1);
std::thread t2(threadfunc,2);
std::thread t3(threadfunc,3);
t1.join();
t2.join();
t3.join();
std::cout<<i<<std::endl;
}
รหัสนี้จะแสดงผลเป็น "2349", "3249", "4239", "4329", "2439" หรือ "3429" แต่จะไม่เป็นอย่างอื่น แต่ละเธรดมีสำเนาของตัวเองi
ซึ่งกำหนดให้เพิ่มขึ้นแล้วพิมพ์ เธรดที่รันmain
ยังมีสำเนาของตัวเองซึ่งถูกกำหนดให้ในตอนเริ่มต้นจากนั้นปล่อยให้ไม่มีการเปลี่ยนแปลง สำเนาเหล่านี้เป็นเอกเทศโดยสิ้นเชิงและแต่ละฉบับมีที่อยู่ที่แตกต่างกัน
มันเป็นเพียงชื่อที่พิเศษในแง่นั้น --- ถ้าคุณใช้แอดเดรสของthread_local
ตัวแปรคุณก็แค่มีตัวชี้ปกติไปยังวัตถุปกติซึ่งคุณสามารถส่งผ่านระหว่างเธรดได้อย่างอิสระ เช่น
thread_local int i=0;
void thread_func(int*p){
*p=42;
}
int main(){
i=9;
std::thread t(thread_func,&i);
t.join();
std::cout<<i<<std::endl;
}
ตั้งแต่ที่อยู่ของผู้i
ถูกส่งไปยังฟังก์ชั่นด้ายแล้วคัดลอกของที่อยู่ในหัวข้อหลักสามารถกำหนดให้แม้ว่าจะเป็นi
thread_local
โปรแกรมนี้จะแสดงผลเป็น "42" หากคุณทำเช่นนี้คุณต้องดูแลที่*p
ไม่สามารถเข้าถึงได้หลังจากเธรดที่เป็นของออกไปมิฉะนั้นคุณจะได้รับตัวชี้ห้อยและพฤติกรรมที่ไม่ได้กำหนดเช่นเดียวกับกรณีอื่น ๆ ที่วัตถุที่ชี้ไปถูกทำลาย
thread_local
ตัวแปรจะถูกกำหนดค่าเริ่มต้น "ก่อนใช้งานครั้งแรก" ดังนั้นหากไม่เคยสัมผัสกับเธรดที่กำหนดก็ไม่จำเป็นต้องเริ่มต้น นี่คือการอนุญาตให้คอมไพเลอร์หลีกเลี่ยงการสร้างthread_local
ตัวแปรทุกตัวในโปรแกรมสำหรับเธรดที่มีอยู่ในตัวเองทั้งหมดและไม่สัมผัสกับตัวแปรใด ๆ เช่น
struct my_class{
my_class(){
std::cout<<"hello";
}
~my_class(){
std::cout<<"goodbye";
}
};
void f(){
thread_local my_class unused;
}
void do_nothing(){}
int main(){
std::thread t1(do_nothing);
t1.join();
}
ในโปรแกรมนี้มี 2 เธรด: เธรดหลักและเธรดที่สร้างขึ้นเอง ไม่มีการเรียกเธรดf
ดังนั้นจึงthread_local
ไม่ใช้อ็อบเจ็กต์ ดังนั้นจึงไม่มีการระบุว่าคอมไพเลอร์จะสร้างอินสแตนซ์ 0, 1 หรือ 2 ของอินสแตนซ์my_class
และเอาต์พุตอาจเป็น "", "hellohellogoodbyegoodbye" หรือ "hellogoodbye"
strtok
ได้strtok
เสียแม้ในสภาพแวดล้อมแบบเธรดเดียว