深入理解线程类和线程启动委托

C++编程中,多线程的使用是提高程序性能的一种常见方法。然而,在使用System::Threading::Thread类时,可能会遇到一些限制和挑战。本文将详细讨论这些限制,并提供一些解决方案。

线程类的密封性

首先,了解到System::Threading::Thread类是一个密封类(sealed class),这意味着不能从它派生出新的类。如果Thread类不是密封的,那么可以通过派生一个新类来轻松地实现线程数据的传递。可以在派生类中添加一个结构体成员,然后在启动线程之前填充这个结构体。这将是一种清晰且优雅的方式来传递数据给线程。

线程启动委托的限制

其次,发现线程启动委托(ThreadStart)不接受任何参数。这与CreateThread API函数和CRT函数_beginthread及_beginthreadex不同,后两者允许通过参数传递结构体或类指针给线程。这种差异可能会让感到困惑,因为需要找到一种方法来绕过这些限制。

寻找解决方案

尽管存在这些限制,但肯定有其合理的理由。可能会错过一些关键的功能,比如AllocateDataSlot和AllocateNamedDataSlot。虽然可能还没有完全理解它们的确切用途,但深入研究文档可能会有所帮助。

自定义类实现线程数据传递

目前,找到了一种解决方案,即创建自己的托管类,并在类中添加一个Thread成员。然后在构造函数中使用Thread成员启动线程。虽然不确定这是否是最佳解决方案,但以下程序列表将尝试阐明这一点。

#include "stdafx.h" #using using namespace System; using namespace System::Threading; __gc class CalcThread { public: CalcThread(int num, String *s); private: void ThreadFunc(); Thread *t; int x; String *s1; }; int wmain(void) { CalcThread *c1, *c2, *c3; Console::WriteLine("Starting thread c1"); c1 = new CalcThread(77, "c1"); Console::WriteLine("Starting thread c2"); c2 = new CalcThread(66, "c2"); Console::WriteLine("Starting thread c3"); c3 = new CalcThread(99, "c3"); return 0; } CalcThread::CalcThread(int num, String *s) { x = num; s1 = s; t = new Thread(new ThreadStart(this, &CalcThread::ThreadFunc)); t->Start(); } void CalcThread::ThreadFunc() { Console::WriteLine("Thread {0} has initialized", s1); for (int i = 0; i < 5; i++) { x ^= i; Console::WriteLine("Thread {0} Intermediate Result : {1}", s1, __box(x)); Thread::Sleep(500); } Console::WriteLine("Thread {0} finished with result {1}", s1, __box(x)); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485