Tôi tự hỏi cách tốt nhất để bắt đầu một pthread là thành viên của một lớp C++? Cách tiếp cận của riêng tôi theo sau là một câu trả lời ...Cách tốt nhất để bắt đầu một chủ đề với tư cách là thành viên của một lớp C++?
Trả lời
Tôi thường sử dụng hàm thành viên tĩnh của lớp và sử dụng con trỏ trỏ đến lớp làm tham số void *. Sau đó hàm đó có thể thực hiện xử lý luồng, hoặc gọi một hàm thành viên không tĩnh khác với tham chiếu lớp. Hàm đó sau đó có thể tham khảo tất cả các thành viên của lớp mà không có cú pháp khó xử.
Bạn phải bootstrap nó bằng cách sử dụng void * Tham số:
class A { static void* StaticThreadProc(void *arg) { return reinterpret_cast<A*>(arg)->ThreadProc(); } void* ThreadProc(void) { // do stuff } }; ... pthread_t theThread; pthread_create(&theThread, NULL, &A::StaticThreadProc, this);
Cảm ơn vì điều này khi tôi nghiên cứu pthread hiện tại của mình trong vấn đề C++. Tuy nhiên, điều này không xung đột hiệu quả với câu trả lời ở đây: http://stackoverflow.com/questions/592160/static-vs-extern-c. Bạn không cần phải thêm extern "C" bằng cách nào đó? Ngoài ra, có bất kỳ vấn đề với làm công việc thực tế trong StaticThreadProc? –
này có thể chỉ đơn giản là thực hiện bằng cách sử dụng thư viện tăng, như thế này:
#include <boost/thread.hpp>
// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}
// construct an instance of the widget modeller or controller
cWidget theWidget;
// start new thread by invoking method run on theWidget instance
boost::thread* pThread = new boost::thread(
&cWidget::Run, // pointer to member function to execute in thread
&theWidget); // pointer to instance of class
Ghi chú:
- Điều này sử dụng một hàm thành viên lớp bình thường. Không cần phải thêm các thành viên phụ, tĩnh làm lẫn lộn giao diện lớp học của bạn
- Chỉ cần bao gồm boost/thread.hpp trong tệp nguồn nơi bạn bắt đầu chuỗi. Nếu bạn chỉ mới bắt đầu với việc tăng cường, tất cả phần còn lại của gói lớn và đáng sợ đó có thể bị bỏ qua.
Trong C++ 11 bạn có thể làm như vậy nhưng không có tăng
// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}
// construct an instance of the widget modeller or controller
cWidget theWidget;
// start new thread by invoking method run on theWidget instance
std::thread * pThread = new std::thread(
&cWidget::Run, // pointer to member function to execute in thread
&theWidget); // pointer to instance of class
Vì vậy, tôi không phản đối điều này ... nhưng không có ai trong cửa hàng tôi làm việc tại sử dụng tăng ...nó sẽ là một sự thay đổi mô hình lớn. Đó là một thư viện khá lớn cũng ... cách tốt nhất để bắt đầu giới thiệu bằng cách sử dụng nó là gì ?? – jdt141
Vâng, nó không thực sự là một thư viện ở tất cả, chỉ là một bó bao gồm. Vì vậy, bạn có thể chọn ra một phần nhỏ của nó mà bắt ưa thích của bạn và bắt đầu bằng cách bao gồm các tiêu đề mà bạn cần chúng. Chỉ cần một vài tính năng ngôn ngữ mới gọn gàng mà bạn có thể sử dụng ở đây và ở đó có vẻ thích hợp. – ravenspoint
+1 để tăng tốc! Không phải để nitpick, nhưng không nên biến 'cMyClass theClass' thực sự được gọi là' cMyClass theObject' vì nó không phải là một lớp học nhưng chỉ là một ví dụ? Tôi nghĩ điều này sẽ rõ ràng hơn. –
Tôi đã sử dụng ba phương pháp nêu trên. Khi lần đầu tiên tôi sử dụng luồng trong c + +, tôi đã sử dụng chức năng thành viên tĩnh, sau đó chức năng bạn bè và cuối cùng là thư viện BOOST. Hiện tại tôi thích BOOST hơn. Trong vài năm qua tôi đã trở thành khá lớn BOOST.
BOOST là C++ là CPAN là Perl. :)
Thư viện tăng cung cấp cơ chế sao chép, giúp chuyển thông tin đối tượng sang chuỗi mới. Trong ví dụ boost boost khác :: bind sẽ được sao chép với một con trỏ, cũng chỉ được sao chép. Vì vậy, bạn sẽ phải chăm sóc cho tính hợp lệ của đối tượng của bạn để ngăn chặn một con trỏ lơ lửng. Nếu bạn thực hiện toán tử() và cung cấp một hàm tạo bản sao thay thế và truyền trực tiếp đối tượng, bạn không phải quan tâm đến nó.
Một giải pháp tốt hơn nhiều, trong đó ngăn chặn rất nhiều rắc rối:
#include <boost/thread.hpp>
class MyClass {
public:
MyClass(int i);
MyClass(const MyClass& myClass); // Copy-Constructor
void operator()() const; // entry point for the new thread
virtual void doSomething(); // Now you can use virtual functions
private:
int i; // and also fields very easily
};
MyClass clazz(1);
// Passing the object directly will create a copy internally
// Now you don't have to worry about the validity of the clazz object above
// after starting the other thread
// The operator() will be executed for the new thread.
boost::thread thread(clazz); // create the object on the stack
Việc tăng khác ví dụ tạo ra các đối tượng thread trên heap, mặc dù không có tinh thần để làm điều đó.
Điều gì xảy ra nếu có hai hoặc nhiều phương thức khác nhau trong lớp bạn cần chạy? Sử dụng toán tử() là thông minh (tốt?) Nhưng nó là cách tốt nhất, cho rằng bạn chỉ có thể có một lớp cho mỗi lớp? – ravenspoint
Một ý nghĩ khác: nhấn mạnh vào việc sao chép lớp mỗi khi phương pháp được khởi động có thể không phải là cách tốt nhất nếu bản sao lớp đắt tiền (ví dụ: yêu cầu nhiều bộ nhớ) hoặc thậm chí có thể phá vỡ thiết kế nếu lớp đó là một singleton. Trong mọi trường hợp, những gì đang xảy ra sẽ phải được ghi chép cẩn thận vì nhiều thứ đang diễn ra hơn là chỉ cần chạy một phương thức. – ravenspoint
Đó là một ý tưởng tốt đẹp để bọc một cơ chế, cho phép bạn gọi một số chức năng trên một lớp học, nhưng bạn hiếm khi sẽ cần nó. Đầu tiên tôi nghĩ đó là một cách tốt đẹp, nhưng sau đó tôi nhận thấy các tác dụng phụ. Nếu bạn thực hiện một cái gì đó với một cơ chế sao chép, tôi muốn nó. Việc truyền đối tượng thay vì con trỏ tới dấu ngoặc tăng :: bind sẽ sao chép đối tượng nhiều lần. Nhưng nếu không bạn sẽ gặp rắc rối trong hầu hết các trường hợp, ngoại trừ Singletons và quản lý đối tượng 'điên' – CSpille
- 1. Cách tốt nhất để bắt đầu với NHibernate là gì?
- 2. Cách tốt nhất để bắt đầu với OSGI là gì?
- 3. PHP5. Hai cách khai báo một mảng là một thành viên của lớp
- 4. Cách tốt nhất để cắt bớt phần đầu của một tập tin trong C là gì?
- 5. Lớp thành viên tĩnh - khai báo lớp riêng tư và lớp thành viên riêng tư?
- 6. Chủ đề: Cách bắt đầu lại chuỗi khi hoàn thành?
- 7. Cách tốt nhất để có được một cuộc gọi lại từ một thể hiện của một lớp C++ gốc thành một lớp ref C++/CX là gì?
- 8. Cách tốt nhất để thu gọn các hàng của một SELECT thành một chuỗi là gì?
- 9. Cách khởi tạo shared_ptr là thành viên của lớp học?
- 10. Cách tốt nhất để bố trí lớp C# là gì?
- 11. Làm thế nào để ẩn các thành viên tư nhân của một lớp học?
- 12. cách tốt nhất để gửi tin nhắn cho chủ đề
- 13. Cách bắt đầu chủ đề đã dừng
- 14. Bắt tên lớp của lớp Đầu tư xây dựng
- 15. Cho phép một lớp "bạn" chỉ truy cập một số thành viên riêng tư
- 16. Cách tốt nhất để cấp phép phần mềm của Microsoft với tư cách là nhà phát triển độc lập
- 17. Làm cách nào để lớp học chỉ có thể truy cập một số thành viên riêng tư của một lớp học khác?
- 18. Cách tốt nhất để bắt đầu dự án
- 19. là có thể sử dụng QtConcurrent :: run() với một thành viên chức năng của một lớp
- 20. C# Luận văn - Cách bắt đầu và dừng một chủ đề
- 21. Clojure cách tốt nhất để đạt được nhiều chủ đề?
- 22. Cách tốt nhất để sử dụng memcache với ứng dụng một máy chủ là gì?
- 23. Nhà cung cấp tư cách thành viên ASP.NET với EF
- 24. Cách tốt nhất để kiểm tra xem System.Type là một hậu duệ của một tầng lớp nhất định
- 25. cách truy cập vào các thành viên riêng tư của lớp lồng nhau?
- 26. Nơi tốt nhất để bắt đầu học Qt là gì?
- 27. Cách tốt nhất để bắt đầu sử dụng MAPI là gì?
- 28. Cách tốt nhất để làm quen với một codebase lớn là gì?
- 29. Cách tốt nhất để thiết kế một máy chủ GWT "Platform-Independent" là gì?
- 30. Làm cách nào để chuyển một hàm thành viên của lớp như một cuộc gọi lại?
Chức năng trình bao bọc phải có liên kết C. Chức năng con trỏ của các chức năng miễn phí có thể không tương thích do liên kết ngôn ngữ – sellibitze