ข้ามไปที่เนื้อหาหลัก

เรื่องวุ่นๆ ของ std::thread ใน C++0x

ถึงแม้ว่าผมเองจะเขียน C++ มาตั้งแต่ตอนเรียนปี 1 แต่หลายๆ ครั้งก็ยังสับสนเรื่องชนิดของตัวแปรอยู่ดี หลังจากปี 1 ก็เขียนมาหลายภาษา ไม่ว่าจะเป็น JAVA PHP Python ยิ่งส่งผลให้สับสนเรื่องลักษณะเด่นของแต่ละภาษา มาวันนี้เริ่มลองเขียน thread ใน C++0x ก็เจอดีอีกจนได้ เนื่องจาก object ใน C/C++ เป็น strong type ไม่เหมือนใน JAVA ที่เป็น reference พอเขียนให้เธรดทำงานจากนั้นไปเปลี่ยนแปลงสมาชิกข้อมูลของ class แต่ object ที่รันอยู่โดย std::thread กลับไม่เปลี่ยนแปลงอะไรเลย โจทย์คือทำอย่างไรให้ object มันใช้ข้อมูลร่วมกันได้ หาไปหามาปรากฎว่าเป็นเพราะไม่ยอมอ่าน doc นี่เอง !!_ _ Multi-threading in C++0x ได้แสดงตัวอย่างการใช้งานไว้ค่อนข้างละเอียดทีเดียว เลยลองมาเขียนเองเล่นๆ ดังตัวอย่างด้านล่าง
#include <iostream>
#include <thread>
using namespace std;

class DoWork
{
public:
DoWork(){
cout << "this in constructor : " << this << endl;
this->running = false;
}

bool running;

void operator()(){

cout << "show running by operator : " << running << endl;
cout << "show this by operator : " << this << endl;
sleep(2);
cout << "show running by operator after wake up : "<< running << endl;

}

void showRunning(){
cout << "show running : " << running << endl;
cout << "show this in show : " << this << endl;
}
};


int main(){

//pass dw to thread by value
cout << "pass dw1 to thread" << endl;
DoWork dw1;
dw1.showRunning();
thread t1(dw1);
sleep(1);
dw1.running = true;
dw1.showRunning();
sleep(1);
t1.join();

//pass dw to thread by reference
cout << endl << "pass dw2 to thread" << endl;
DoWork dw2;
dw2.showRunning();
thread t2(std::ref(dw2));
sleep(1);
dw2.running = true;
dw2.showRunning();
t2.join();

return 0;
}


เมื่อคอมไพล์แล้วรันจะได้ผลดังนี้
$ g++ thread_val.cpp --std=c++0x -lpthread
$ ./a.out
pass dw1 to thread
this in constructor : 0x7fff876d184f
show running : 0
show this in show : 0x7fff876d184f
show running by operator : 0
show this by operator : 0x1a55048
show running : 1
show this in show : 0x7fff876d184f
show running by operator after wake up : 0

pass dw2 to thread
this in constructor : 0x7fff876d183f
show running : 0
show this in show : 0x7fff876d183f
show running by operator : 0
show this by operator : 0x7fff876d183f
show running : 1
show this in show : 0x7fff876d183f
show running by operator after wake up : 1
เมื่อทดสอบรันดูจะได้ผลดังที่แสดงไว้ ในตัวอย่างแรก dw1 นั้นผมส่งอ็อบเจกต์ไปให้ contractor ของ std::thread เลย โดยปรกติตัวแปล running จะมีค่าเป็น false แล้วพยายามกำหนดค่าให้ตัวแปล running ซึ่งเป็นสมาชิกของ DoWork เป็น true ผลที่ได้คือตัวแปร running ใน dw1 เป็น true จริง แต่เป็นคนละอ็อบเจกต์กันที่ทำงานอยู่ในเธรด t1 หากสังเกตดูจะพบว่า this pointer จะมี address ต่างกันคือ dw1 ที่อยู่ใน main จะมีค่าเป็น 0x7fff876d184f ส่วนใน t1 จะมีค่าเป็น 0x1a55048 ซึ่งเป็นคนละตำแหน่งกัน
หากพิจารณา dw2 เป็นการส่งผ่านโดยใช้คำสงวน std::ref ไปให้ constractor ของ std::thread t2 จะให้ค่าที่ต่างกันออกไป เนื่องจากอ็อบเจกต์ dw2 ที่ทำงานใน t2 เป็นอ็อบเจกต์เดียวกัน สังเกตได้จาก address ของ this pointer มีค่าเดียวกันคือ 0x7fff876d183f ดังนั้นสามารถกำหนดค่าให้ dw2 ที่รันอยู่ใน t2 ได้ทันที แต่แค่นี้ก็เล่นเอาหอบ :D

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

ตัวเอ๋ยตัวผม

กลอนนี้ใช้เวลาประมาณ 20 นาทีเขียนขึ้นมาในห้องเรียนวิชาสัมนา 1 เพราะอาจารย์อยากให้แนะนำตัวเองเป็นกลอน ไม่รู้จะแต่งว่าไงเลยแต่งออกมาเป็นดอกสร้อย เห็นว่าพอใช้ได้เลยเอามาลงไว้เป็นอนุสร ๏ ตัวเอ๋ยตัวผม นิยมในพระพุทธศาสนา ตั้งจิตตั้งใจตั้งหน้า ใฝ่หาความรู้สู่ตน ตั้งใจศึกษาให้เชี่ยวชาญ ชำนาญในศาสตร์ที่ฝึกฝน ฝึกจิตฝึกสันดานให้เป็นคน เป็นชนในชาติที่ดีเอย ๚ะ๛

บันทึกการจัดงานศพ: พิธีฌาปนกิจศพ

ตรงส่วนนี้คงจะเขียนเกี่ยวกับพิธียกศพออกจากบ้าน และเกร็ดต่างๆ เล็กๆ น้อยๆ เนื่องจากที่จัดงานจะไม่นิยมไว้ศพที่วัด จะไว้ศพที่บ้าน และถ้าเป็นไปได้จะไว้ศพในบ้านเสียด้วยซ่ำ เมื่อถึงวันฌาปนกิจศพ หรือเผาศพ ก็จะมีการเซ่นไหว้ครั้งใหญ่ก่อนเคลื่อนย้ายศพไปวัดเพื่อฌาปนกิจ เครื่องเซ่นไว้จะประกอบไปด้วย ข้าว 5 ถ้วย กับข้าว 5 อย่าง หัวหมู ไก่ต้ม ไข่ต้ม หมูสามชั้นต้ม หมี่เหลืองผัด กุ้ง หอย ปู ปลา ผลไม้ 5 อย่าง ขนมขึ้น เมื่อมีการเซ่นไหว้ทุกครั้งจะต้องมี สัปรด น้ำชา 3 จอก เหล้าขาว 5 จอก(หลานๆ บอกว่าเจ็คไม่กินเหล้าขาว แต่มีคนบอกว่าเป็นการไหว้ตามประเพณี ^^ ) ซึ่งแต่ละอย่างมีความหมาย แต่ผมจำไม่ได้ต้องหาอีกครั้งนึง ตัวอย่างเครื่องเซ่นไหว้ เมื่อถึงพิธีเซ่นไหว้ จะมีการเซ่นไหว้โดยแบ่งออกเป็นคณะ แต่เพื่อความสะดวกและรวบรัดจึงมีการไหว้เพียงไม่กี่คณะ ซึ่งก็เหมือนเดิมคือผู้ที่มีศักดิ์สูงกว่าจะไม่รวมการเซ่นไหว้ครั้งนี้ คณะแรกจะเป็นผู้ไกล้ชิดผู้ตายมากที่สุดเริ่มตั้งแต่ลูกและภรรยา หลังจากนั้นก็จะเป็นน้องๆ แล้วก็หลานๆ และก็มิตรรักและผู้คนที่นับถือผู้ตาย หากเป็นเมื่อสมัยก่อนนั้น ต้องแยกออกเป็นเขย เป็นสะไภ้ ไหว้กันหลายยกหล

ด้วยระลึกถึงคุณย่า บันทึกจากความทรงจำ

บันทึกนี้เขียนขึ้นเพื่อบันทึกความทรงจำของผมที่มีต่อคุณย่าที่ล่วงลับไปแล้วอย่างไม่มีวันหวนคืน คุณย่าเปรียบเหมือนฟางเส้นสุดท้ายที่ร้อยครอบครัวใหญ่ของเราเอาไว้ไม่ให้แตกแยก หลังจากที่เสียคุณปู่ไปเมื่อ 23 ปีก่อน เนื่องจากบริเวณจังหวัดกระบี่ ตรัง พังงา ภูเก็ต มีชาวจีนอาศัยอยู่มาก แต่มักจะเป็นชาวจีนที่อพยพมาไทยนานแล้ว จากการการสังเกตของผม ชาวจีนแถบนี้โดยมากน่าจะเป็นชาว เปอรานากัน หรือชาวจีนที่อพยพมาจากจีนแล้วตั้งถิ่นฐานอยู่ในแหลมลายูหรืออินโดนีเซีย แล้วหลังจากนั้นจึงอพยพมาอาศัยต่อที่ประเทศไทย จากการบอกเล่าของคุณแม่ ก๋งเคยเล่าให้ฟังว่าตอนยังเด็กเคยแจวเรือจ้างอยู่ที่ปีนัง คุณย่าเคยเล่าว่าเป็นชาวฮกเกี้ยน อีกทั้วจากรูปวาดคุณย่าทวดที่มีการเกล้ามวยผม สวมเสื้อคอลึก ส่วนทางบ้านมีการใช้คำเรียกจีนผสมไทยถิ่นใต้อยู่มาก ผู้หญิงทุกคนนิยมสวมผ้าปาเต๊ะ เสื้อลูกไม้ (เสื้อฉลุลายดอกไม้) อาหารการกินเป็นแบบชาวไทยถิ่นใต้ทุกประการ (กินน้ำพริก แกงส้มเก่งกันทุกคน ยกเว้นก๋ง :D) อีกทั้งก๋งเกิดที่ดินแดนแถบนี้ไม่ได้เดินทางมาจากเมืองจีน (บางทีเรียก เตี่ยต่อเตี่ย คือ ทวดมาจากจีน ส่วนสถานที่เกิดไม่แน่ใจว่าเป็นปีนังหรือไทย)