Đa luồng là dạng đặc biệt của đa nhiệm. Đa nhiệm cho phép máy tính chạy hai hoặc nhiều chương trình đồng thời. Có hai loại đa nhiệm: dựa trên tiến trình và dựa trên luồng.
Đa nhiệm dựa trên tiến trình xử lý thực thi đồng thời các chương trình. Đa nhiệm dựa trên luồng xử lý thực thi đồng thời các phần của cùng một chương trình.
Chương trình đa luồng chứa hai hoặc nhiều phần chạy đồng thời. Mỗi phần gọi là một luồng, mỗi luồng định nghĩa một đường thực thi riêng.
C không có hỗ trợ tích hợp cho ứng dụng đa luồng. Thay vào đó, nó hoàn toàn phụ thuộc vào hệ điều hành cung cấp tính năng này.
Hướng dẫn này giả định bạn làm việc trên Linux OS và viết chương trình C đa luồng dùng POSIX. POSIX Threads (Pthreads) cung cấp API có sẵn trên nhiều hệ Unix-like như FreeBSD, NetBSD, GNU/Linux, Mac OS X và Solaris.
Hàm sau dùng để tạo luồng POSIX:
#include <pthread.h> pthread_create(thread, attr, start_routine, arg)
Ở đây, pthread_create tạo luồng mới và làm cho nó có thể thực thi. Hàm này có thể gọi nhiều lần từ bất kỳ đâu trong mã. Mô tả tham số:
| Tham số | Mô tả |
|---|---|
| thread | Định danh mờ, duy nhất cho luồng mới do hàm con trả về. |
| attr | Đối tượng thuộc tính mờ dùng để thiết lập thuộc tính luồng. Có thể chỉ định đối tượng thuộc tính luồng hoặc NULL cho giá trị mặc định. |
| start_routine | Hàm C mà luồng sẽ thực thi sau khi được tạo. |
| arg | Đối số đơn có thể truyền cho start_routine. Phải truyền bằng tham chiếu dưới dạng con trỏ kiểu void. NULL nếu không truyền đối số. |
Số luồng tối đa một tiến trình có thể tạo phụ thuộc vào triển khai. Sau khi tạo, các luồng là ngang hàng, có thể tạo luồng khác. Không có thứ bậc hoặc phụ thuộc ngầm giữa các luồng.
Kết thúc luồng
Hàm sau dùng để kết thúc luồng POSIX:
#include <pthread.h> pthread_exit(status)
pthread_exit dùng để thoát rõ ràng khỏi luồng. Thường gọi sau khi luồng hoàn thành công việc và không còn cần thiết.
Nếu main() kết thúc trước các luồng đã tạo, và thoát bằng pthread_exit(), các luồng khác sẽ tiếp tục thực thi. Ngược lại, chúng sẽ tự động kết thúc khi main() kết thúc.
Ví dụ mã
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 5
void *PrintHello(void *threadid) {
long tid;
tid = (long)threadid;
printf("Hello World! Thread ID, %d\n", tid);
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) {
printf("Error:unable to create thread, %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}Kết quả
$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