2017-04-26 22 views
7

Xem xét trường hợp bên dướiTruy cập std đã di chuyển :: chuỗi trong một chủ đề mới

Chuỗi tên được di chuyển làm đối số cho chuỗi.

void start(std::string&& name) { 
     t = std::thread{&ThreadRunner::run, this, std::forward<std::string>(name)}; 
    } 

Chức năng chạy của chuỗi cũng có tham chiếu rvalue.

void run(std::string&& name) { 
     const auto errnum = pthread_setname_np(t.native_handle(), name.c_str()); 
     if (errnum != 0) { 
      std::cout << "ERROR " << std::endl; 
     } 
    } 

Các chủ đề được tạo ra thông qua chức năng bắt đầu như sau:

ThreadRunner r; 
    r.start(std::string("somename")); 

Câu hỏi đặt ra là. Có thể là chuỗi std :: được truy cập trong hàm run thông qua pthread_setname_np có thể là thư rác vì tạm thời không thuộc phạm vi khi phạm vi kết thúc?

Demo Trong bản demo trên, sau khi call kết thúc, là nó guranteed rằng chuỗi somename là hợp lệ trong hàm run?

Chỉnh sửa: Demo with constructors/destructors Chuỗi std :: bây giờ được thay thế bằng Wrap để in các nhà thầu liên quan.

Kết quả là: (lĩnh vực thứ hai là địa chỉ của đối tượng, thứ ba là thread id)

Constructed 0x7ffc395e0ef0 140605000369984 
Move Constructed 0x7ffc395e0e60 140605000369984 
Move Constructed 0x177a0a0 140605000369984 
Destroyed 0x7ffc395e0e60 140605000369984 
Destroyed 0x7ffc395e0ef0 140605000369984 
Call ended 

somename 
Destroyed 0x177a0a0 140604983461632 

Đối tượng cuối cùng, bị phá hủy sau khi run kết thúc. Liệu nó vẫn chỉ tạm thời. Tôi nghĩ là không.

A more clean example

Edit: Sau những ý kiến, câu hỏi nắm để

"Sau các cuộc gọi ban đầu để làm mất hiệu lực bắt đầu (std :: string & & tên); đã trở lại và sau các nhà xây dựng của std :: thread đã kết thúc, nơi là chuỗi mà void chạy (std :: string & & tên); đang làm việc trên? "

Mã demo mới nhất dường như cho thấy đối tượng Wrap đang được tham chiếu bởi run bị hủy sau khi thoát run.

+7

Thay vì lạm dụng 'std :: forward' cho công việc mà nó không được thiết kế để cung cấp, vui lòng sử dụng' std :: move'. – Rakete1111

+0

@ Rakete1111 Lưu ý. Cảm ơn. – themagicalyang

Trả lời

0

Không có tham chiếu treo lơ lửng, vì đối số hàm tạo của std::thread được sao chép/di chuyển vào một số cấu trúc theo chuỗi khách hàng. Chuỗi mới được tạo sau đó sẽ chạy trên các đối tượng được sao chép/di chuyển trong cấu trúc này.

Trong trường hợp cụ thể của bạn, đối tượng std::string thực sự được chuyển vào cấu trúc được mô tả. Đó là đối tượng std::stringrun() đang hoạt động. Nó sẽ được tiêu hủy đúng khi luồng kết thúc thực hiện.

Các vấn đề liên quan