Tải bản đầy đủ (.pdf) (9 trang)

Đa luồng (Multithread) trong C++ | 101 bài hướng dẫn C++ hay nhất PDF

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (375.01 KB, 9 trang )

/>
Copyright © vietjack.com

Đa luồng (Multithread) trong C++
Đa luồng (Multithreading) là một form chuyên dụng của đa nhiệm (multitasking) và một đa nhiệm
là tính năng cho phép máy tính của bạn chạy hai hoặc nhiều chương trình đồng thời. Nói chung, có
hai kiểu đa nhiệm là: process-based và thread-based tương ứng: 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ý việc thực thi đồng thời của các chương trình. Đa nhiệm dựa trên
luồng xử lý việc thực thi đồng thời các phần của cùng một chương trình.
Một chương trình đa luồng chứa hai hoặc nhiều phần mà có thể chạy đồng thời. Mỗi phần của
chương trình đó được gọi là một thread, và mỗi thread định nghĩa một path riêng biệt của sự thực
thi.
C++ không chứa bất kỳ hỗ trợ có sẵn nào cho các ứng dụng đa luồng. Thay vào đó, nó dựa hoàn
toàn vào Hệ điều hành để cung cấp tính năng này.
Chương này giả sử bạn đang làm việc trên Hệ điều hành Linux và chúng tôi đang chuẩn bị viết
chương trình đa luồng trong C++ bởi sử dụng POSIX. POSIX Threads hoặc Pthreads cung cấp
API mà có sẵn trên nhiều hệ thống như FreeBSD, NetBSD, GNU/Linux, Mac OS X và Solaris.

Tạo Thread trong C++
Đây là chương trình chúng ta sử dụng để tạo một POSIX thread:
#include
pthread_create (thread, attr, start_routine, arg)

Ở đây, pthread_create tạo một thread mới và làm nó có thể thực thi. Chương trình này có thể
được gọi bất cứ thời điểm nào ở bất cứ đâu trong code của bạn. Dưới đây là miêu tả các tham số:
Tham số

Miêu tả

thread



Một định danh duy nhất cho thread mới được trả về bởi chương trình
con

Trang chia sẻ các bài học online miễn phí

Page 1


/>
Copyright © vietjack.com

attr

Một thuộc tính mà có thể được sử dụng để thiết lập các thuộc tính của
thread. Bạn có thể xác định một đối tượng thuộc tính thread, hoặc
NULL cho các giá trị mặc định

start_routine

Chương trình C++ mà thread này sẽ thực thi một khi nó được tạo

arg

Một tham số đơn mà có thể được truyền tới start_routine. Nó phải
được truyền bởi tham chiếu dạng một con trỏ của kiểu void. NULL có
thể được sử dụng nếu không có tham số nào được truyền

Số thread tối đa có thể được tạo bởi một tiến trình là phụ thuộc vào trình triển khai
(Implementation). Một khi được tạo, các thread là ngang hàng, và có thể tạo các thread khác.

Không có sự phụ thuộc giữa các thread trong C++.

Kết thuốc Thread trong C++
Chương trình sau được sử dụng để kết thúc một POSIX thread trong C++:
#include
pthread_exit (status)

Ở đây pthread_exit được sử dụng để kết thúc một thread. Chương trình pthread_exit() được gọi
sau khi một thread đã hoàn thành công việc của nó và không cần thiết phải tồn tại nữa.
Nếu main() kết thúc trước các thread nó đã tạo, và kết thúc chương trình pthread_create(), thì các
thread khác sẽ tiếp tục thực thi. Nếu không thì, chúng sẽ tự động được kết thúc khi main() hoàn
thành.

Ví dụ
Ví dụ đơn giản sau tạo 5 thread với chương trình pthread_create(). Mỗi thread in một thông báo
“Hello World!”, và sau đó kết thúc với một lời gọi tới pthread_exit() trong C++:
#include <iostream>
#include <cstdlib>
#include

using namespace std;

Trang chia sẻ các bài học online miễn phí

Page 2


/>
#define NUM_THREADS


Copyright © vietjack.com

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);
}

Biên dịch chương trình trên sử dụng thư viện –lpthread như sau:

$gcc test.cpp -lpthread

Bây giờ, thực thi chương trình sẽ cho kết quả:
main() : creating thread, 0

Trang chia sẻ các bài học online miễn phí

Page 3


/>
Copyright © vietjack.com

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

Truyền tham số tới Thread trong C++
Ví dụ này minh họa cách truyền nhiều tham số thông qua một cấu trúc. Bạn có thể truyền bất kỳ
kiểu dữ liệu nào trong một Thread callback, bởi vì nó trỏ tới void như được giải thích trong ví dụ
sau:
#include <iostream>
#include <cstdlib>
#include


using namespace std;

#define NUM_THREADS

5

struct thread_data{
int

thread_id;

char *message;
};

void *PrintHello(void *threadarg)
{
struct thread_data *my_data;

my_data = (struct thread_data *) threadarg;

Trang chia sẻ các bài học online miễn phí

Page 4


/>
Copyright © vietjack.com

cout << "Thread ID : " << my_data->thread_id ;

cout << " Message : " << my_data->message << endl;

pthread_exit(NULL);
}

int main ()
{
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc;
int i;

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

Khi code trên được biên dịch và thực thi, nó cho kết quả sau:
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2

main() : creating thread, 3
main() : creating thread, 4

Trang chia sẻ các bài học online miễn phí

Page 5


/>
Copyright © vietjack.com

Thread ID : 3 Message : This is message
Thread ID : 2 Message : This is message
Thread ID : 0 Message : This is message
Thread ID : 1 Message : This is message
Thread ID : 4 Message : This is message

Kết hợp và Tháo gỡ các Thread trong C++
Hai cú pháp sau được sử dụng để kết hợp (joining) hoặc tháo gỡ (detaching) các Thread trong
C++:
pthread_join (threadid, status)
pthread_detach (threadid)

Chương trình con pthread_join() đóng khối thread đang gọi tới khi threadid kết thúc. Khi một thread
được tạo, một trong các thuộc tính định nghĩa nó là joinable hoặc detached. Chỉ các thread được
tạo với dạng joinable có thể được kết hợp. Nếu một thread được tạo với dạng detached, nó không
bao giờ được kết hợp.
Ví dụ sau minh họa cách đợi cho các thread kết thúc bởi sử dụng chương trình kết hợp Pthread
trong C++:
#include <iostream>

#include <cstdlib>
#include
#include <unistd.h>

using namespace std;

#define NUM_THREADS

5

void *wait(void *t)
{
int i;
long tid;

Trang chia sẻ các bài học online miễn phí

Page 6


/>
Copyright © vietjack.com

tid = (long)t;

sleep(1);
cout << "Sleeping in thread " << endl;
cout << "Thread with id : " << tid << "

...exiting " << endl;


pthread_exit(NULL);
}

int main ()
{
int rc;
int i;
pthread_t threads[NUM_THREADS];
pthread_attr_t attr;
void *status;

// Initialize and set thread joinable
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

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

// free attribute and wait for the other threads
pthread_attr_destroy(&attr);
for( i=0; i < NUM_THREADS; i++ ){
rc = pthread_join(threads[i], &status);


Trang chia sẻ các bài học online miễn phí

Page 7


/>
Copyright © vietjack.com

if (rc){
cout << "Error:unable to join," << rc << endl;
exit(-1);
}
cout << "Main: completed thread id :" << i ;
cout << "

exiting with status :" << status << endl;

}

cout << "Main: program exiting." << endl;
pthread_exit(NULL);
}

Khi code trên được biên dịch và thực thi, nó cho kết quả sau:
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Sleeping in thread

Thread with id : 0 .... exiting
Sleeping in thread
Thread with id : 1 .... exiting
Sleeping in thread
Thread with id : 2 .... exiting
Sleeping in thread
Thread with id : 3 .... exiting
Sleeping in thread
Thread with id : 4 .... exiting
Main: completed thread id :0

exiting with status :0

Main: completed thread id :1

exiting with status :0

Main: completed thread id :2

exiting with status :0

Main: completed thread id :3

exiting with status :0

Main: completed thread id :4

exiting with status :0

Trang chia sẻ các bài học online miễn phí


Page 8


/>
Copyright © vietjack.com

Main: program exiting.

Trang chia sẻ các bài học online miễn phí

Page 9



×