Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Multithreading ใน C++

Multithreading (หลายเธรด) เป็นรูปแบบเฉพาะของ multitasking (หลายงาน) และ multitasking คือคุณสมบัติที่ทำให้คอมพิวเตอร์รันโปรแกรมได้ 2 ตัวขึ้นไปพร้อมกัน โดยทั่วไปมี 2 ประเภทของ multitasking:

  • Process-based multitasking: จัดการการทำงานพร้อมกันของโปรแกรมต่างๆ
  • Thread-based multitasking: จัดการการทำงานพร้อมกันของส่วนต่างๆ ในโปรแกรมเดียวกัน

โปรแกรม multithreaded ประกอบด้วย 2 ส่วนขึ้นไปที่รันพร้อมกันได้ แต่ละส่วนเรียกว่า thread (เธรด) และแต่ละ thread กำหนด path of execution (เส้นทางการทำงาน) แยกกัน

C++ ไม่มีการสนับสนุน multithreaded applications แบบ built-in แต่พึ่งพา operating system ทั้งหมดในการให้คุณสมบัตินี้

บทช่วยสอนนี้สมมติว่าคุณทำงานบน Linux OS และเราจะเขียนโปรแกรม C++ หลายเธรดโดยใช้ POSIX (POSIX Threads หรือ Pthreads) ซึ่งให้ API ที่ใช้ได้บนระบบ Unix-like หลายๆ ระบบ เช่น FreeBSD, NetBSD, GNU/Linux, Mac OS X และ Solaris

การสร้าง POSIX Thread

ฟังก์ชันต่อไปนี้ใช้สร้าง POSIX thread:

#include <pthread.h>
pthread_create(thread, attr, start_routine, arg)

โดยที่ pthread_create สร้างเธรดใหม่และทำให้ executable ได้ สามารถเรียกได้หลายครั้งจากที่ไหนก็ได้ในโค้ด คำอธิบายพารามิเตอร์:

ParameterDescription
threadตัวระบุเธรดที่ไม่ซ้ำกัน คืนค่าจาก subroutine
attrอ็อบเจ็กต์แอตทริบิวต์สำหรับตั้งค่าเธรด สามารถระบุ NULL สำหรับค่าเริ่มต้น
start_routineฟังก์ชัน C++ ที่เธรดจะรันเมื่อถูกสร้าง
argอาร์กิวเมนต์เดียวที่ส่งให้ start_routine ต้องส่งแบบ reference ผ่าน void pointer ใช้ NULL ถ้าไม่ต้องส่งอาร์กิวเมนต์

จำนวนเธรดสูงสุดที่ process สร้างได้ขึ้นอยู่กับ implementation เธรดที่สร้างแล้วเป็น peers และสามารถสร้างเธรดอื่นได้ ไม่มี hierarchy หรือ dependency ระหว่างเธรด

การสิ้นสุดเธรด (Terminating Threads)

ใช้ฟังก์ชันต่อไปนี้เพื่อสิ้นสุด POSIX thread:

#include <pthread.h>
pthread_exit(status)

pthread_exit ใช้ออกจากเธรดโดยตรง โดยทั่วไปจะเรียกหลังจากเธรดทำงานเสร็จและไม่จำเป็นต้องมีอยู่ต่อ หาก main() จบก่อนเธรดที่สร้าง และออกด้วย pthread_exit() เธรดอื่นๆ จะยังทำงานต่อไป มิฉะนั้น จะถูก terminated อัตโนมัติเมื่อ main() จบ

ตัวอย่างโค้ด

#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;

#define NUM_THREADS 5

void *PrintHello(void *threadid) {
    long tid;
    tid = (long)threadid;
    cout << "Hello World! Thread ID, " << tid << endl;
    pthread_exit(NULL);
}

int main() {
    pthread_t threads[NUM_THREADS];
    int rc;
    int i;
    for (i = 0; i < NUM_THREADS; i++) {
        cout << "main() : creating thread, " << i << endl;
        rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i);
        if (rc) {
            cout << "Error: unable to create thread, " << rc << endl;
            exit(-1);
        }
    }
    pthread_exit(NULL);
}

ผลลัพธ์

$ gcc test.cpp -lpthread
$ ./a.out
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Hello World! Thread ID, 0
Hello World! Thread ID, 1
Hello World! Thread ID, 2
Hello World! Thread ID, 3
Hello World! Thread ID, 4