2013-03-01 32 views
21

By definition from C++ reference:STD :: thread.join() làm gì?

Blocks thread hiện hành cho đến khi thread xác định bởi *this kết thúc thực hiện của nó.

Vì vậy, điều này có nghĩa là khi sử dụng .join(), không cần phải mutex.lock() khi chuỗi đó gọi một số chức năng? Tôi mới để loại trừ lẫn nhau và luồng, vì vậy tôi là loại bối rối.

Lưu ý: Tôi đã tìm thấy một cuốn sách C++ Đồng thời trong hành động và tôi đang đọc sách. Nó được viết rất tốt cho người mới bắt đầu về đa luồng như tôi.

Cảm ơn tất cả vì sự giúp đỡ.

+3

Cảm ơn bạn đã David chỉnh sửa để làm rõ hơn. Martin: Tôi đã thử google nhưng tôi thấy 4-5 mẫu có cùng ý tưởng và không thực sự hiển thị những gì tham gia đang làm từ quan điểm của tôi .. Tôi nghĩ ppl ở đây có kiến ​​thức và sẽ cung cấp câu trả lời tốt nhất với mã mẫu. – Guagua

Trả lời

17

Bạn vẫn cần các điều kiện và mutex. Tham gia một chuỗi làm cho một luồng thực hiện chờ một luồng khác kết thúc chạy. Bạn vẫn cần mutexes để bảo vệ tài nguyên được chia sẻ. Nó cho phép main() trong ví dụ này chờ tất cả các luồng kết thúc trước khi thoát khỏi chính nó.

#include <iostream> 
#include <thread> 
#include <chrono> 
#include <mutex> 

using namespace std; 



int global_counter = 0; 
std::mutex counter_mutex; 

void five_thread_fn(){ 
    for(int i = 0; i<5; i++){ 
     counter_mutex.lock(); 
     global_counter++; 
     counter_mutex.unlock(); 
     std::cout << "Updated from five_thread" << endl; 
     std::this_thread::sleep_for(std::chrono::seconds(5)); 
    } 
    //When this thread finishes we wait for it to join 
} 

void ten_thread_fn(){ 
    for(int i = 0; i<10; i++){ 
     counter_mutex.lock(); 
     global_counter++; 
     counter_mutex.unlock(); 
     std::cout << "Updated from ten_thread" << endl; 
     std::this_thread::sleep_for(std::chrono::seconds(1)); 
    } 
    //When this thread finishes we wait for it to join 
} 
int main(int argc, char *argv[]) { 
    std::cout << "starting thread ten..." << std::endl; 
    std::thread ten_thread(ten_thread_fn); 

    std::cout << "Running ten thread" << endl; 
    std::thread five_thread(five_thread_fn); 


    ten_thread.join(); 
    std::cout << "Ten Thread is done." << std::endl; 
    five_thread.join(); 
    std::cout << "Five Thread is done." << std::endl; 
} 

Lưu ý rằng đầu ra có thể trông như thế này:

starting thread ten... 
Running ten thread 
Updated frUopmd atteend_ tfhrroema df 
ive_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from five_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from five_thread 
Ten Thread is done. 
Updated from five_thread 
Updated from five_thread 
Five Thread is done. 

Kể từ std :: cout là một quyền truy cập tài nguyên chia sẻ và sử dụng nó cũng nên được mutex bảo vệ quá.

+1

Cảm ơn bạn Joel, vì vậy ở đây ten_thread.join() sẽ nói cho chương trình ten_thread được thực hiện và có thể chuyển sang bước tiếp theo? – Guagua

+1

luồng thực thi chạy chính() sẽ chặn tại cuộc gọi của ten_thread.join() cho đến khi trả về ten_thread. Sau khi thực thi lệnh ten_thread kết thúc, việc thực thi của chính được phép tiếp tục. Hi vọng điêu nay co ich. – Joel

6

tham gia() dừng luồng hiện tại cho đến khi kết thúc chuỗi khác. mutex dừng thread hiện tại cho đến khi chủ sở hữu mutex phát hành nó hoặc khóa ngay lập tức nếu nó không bị khóa. Vì vậy, những người này khá khác nhau

+6

Tôi thích "tạm ngưng" thay vì "dừng". – Sebastian

0

std :: Thread.Join có ba chức năng tôi có thể nghĩ ra khỏi tay và một số người khác:

a) Khuyến khích liên tục tạo/chấm dứt/hủy hoại của chủ đề, vì vậy búa hiệu suất và tăng probabilty rò rỉ, thread-runaway, bộ nhớ chạy trốn và mất kiểm soát chung của ứng dụng của bạn.

b) Xử lý sự kiện xử lý sự kiện GUI bằng cách thực thi chờ đợi không mong muốn, dẫn đến 'ứng dụng đồng hồ cát' không phản hồi mà khách hàng của bạn sẽ ghét.

c) Gây ra các ứng dụng không tắt máy vì chúng đang chờ kết thúc chuỗi không thể ngắt kết nối, không ngắt quãng.

d) Những điều xấu khác.

Tôi hiểu rằng bạn mới sử dụng đa luồng và tôi muốn bạn là người tốt nhất với nó. Ngoài ra, hãy xem xét rằng tôi đã có rất nhiều Adnams Broadside tối nay, nhưng:

Tham gia(), và đó là bạn bè bằng các ngôn ngữ khác như TThread.WaitFor, (Delphi), là đa luồng hiệu quả như Windows ME đã hoạt động hệ thống.

Hãy cố gắng hết sức để tiến bộ và tìm hiểu các khái niệm đa luồng khác - nhóm, nhiệm vụ, chuỗi thời gian sử dụng, kết nối giữa các chủ đề thông qua hàng đợi của nhà sản xuất. Trong thực tế, hầu hết mọi thứ ngoại trừ Join().

+3

Hi Martin, bất kỳ đề nghị đọc về Multithreading trong c + +? – Guagua

1

Nó chặn luồng hiện tại cho đến khi việc thực hiện xong chuỗi được kết nối trên đó tham gia() được gọi.

Nếu bạn không chỉ định tham gia() hoặc dettach() trên luồng thì nó sẽ dẫn đến lỗi thời gian chạy vì luồng chính/hiện tại sẽ hoàn tất quá trình thực hiện và chuỗi khác được tạo sẽ vẫn chạy.