【编程开发】AspAsp.NetCGIPHPJspXMLPERLC++C#VCVBDelphiPowerBuilderJAVA汇编数据库编程移动开发其它语言

您现在的位置:首页 > 网络学院 > 编程开发 > C++ > 实例解析C++/CLI线程之多任务

实例解析C++/CLI线程之多任务

来源: 作者: 日期:2006-11-02

【聚杰网C++】实例解析C++/CLI线程之多任务

  一个重入的函数可由多个线程安全地并行执行。当线程开始执行一个函数时,在函数中分配的所有数据都来自栈或堆,但无论如何,对此调用来说,都是唯一的。如果在另一个线程仍处于工作状态时,本线程开始执行同一个函数,那么,每个线程中的数据都是相互独立的。然而,如果函数访问线程间共享的变量或文件时,则必须使用某些同步方法。

  创建线程

  在例1中,主线程创建了两个其他的线程,这三个线程并行运行,并且未进行同步。在线程间并未共享数据,且当最后一个线程结束时,主进程也结束了。

  例1:

using namespace System;
using namespace System::Threading;

public ref class ThreadX
{
 int loopStart;
 int loopEnd;
 int dispFrequency;
 public:
  ThreadX(int startValue, int endValue, int frequency)
  {
   loopStart = startValue;
   loopEnd = endValue;
   dispFrequency = frequency;
  }

  /*1*/ void ThreadEntryPoint()
  {
   /*2*/ String^ threadName = Thread::CurrentThread->Name;

   for (int i = loopStart; i <= loopEnd; ++i)
   {
    if (i % dispFrequency == 0)
    {
     Console::WriteLine("{0}: i = {1,10}", threadName, i);
    }
   }
   Console::WriteLine("{0} thread terminating", threadName);
  }
};

int main()
{
 /*3a*/ ThreadX^ o1 = gcnew ThreadX(0, 1000000, 200000);
 /*3b*/ Thread^ t1 = gcnew Thread(gcnew ThreadStart(o1, &ThreadX::ThreadEntryPoint));
 /*3c*/ t1->Name = "t1";

 /*4a*/ ThreadX^ o2 = gcnew ThreadX(-1000000, 0, 200000);
 /*4b*/ Thread^ t2 = gcnew Thread(gcnew ThreadStart(o2, &ThreadX::ThreadEntryPoint));
 /*4c*/ t2->Name = "t2";

 /*5*/ t1->Start();
 /*6*/ t2->Start();
 Console::WriteLine("Primary thread terminating");
}

  请看标记3a中第一条可执行语句,此处我们创建了一个用户自定义ThreadX类型的对象,这个类有一个构造函数、一个实例函数及三个字段。我们调用构造函数时,传递进一个开始、一个结束计数,及一个固定增量,其用于循环控制。

  在标记3b中,创建了一个库类型System::Thread的对象,它源自命名空间System::Threading,可用此对象来创建一个新的线程,但是,在线程可以工作之前,它必须要知道从哪开始执行,所以传递给Thread构造函数一个System::ThreadStart代理类型,其可支持不接受参数的任意函数,且没有返回值(作为一个代理,它可封装进多个函数,在本例中,只指定了一个)。在上面的代码中,指定了线程由执行对象o1的ThreadEntryPoint实例函数开始,一旦开始之后,这个线程将会执行下去直到函数结束。最后,在标记3c中,随意使用了一个名称,以设置它的Name属性。

  请看标记4a、4b及4c,第二个线程也一样,只不过设置了不同的循环控制及名称。
 
  眼下,已构造了两个线程对象,但并未创建新的线程,也就是说,这些线程处于未激活状态。为激活一个线程,必须调用Thread中的Start函数,见标记5与6。通过调用进入点函数,这个函数启动了一个新的执行线程(对一个已经激活的函数调用Start将导致一个ThreadStateException类型异常)。两个新的线程都各自显示出它们的名称,并在循环中定时地显示它们的进度,因为每个线程都执行其自身的实例函数,所以每个线程都有其自己的实例数据成员集。

  所有三个线程均写至标准输出,见插1,可看出线程中的输出是缠绕在一起的(当然,在后续的执行中,输出也可能有不同的顺序)。可见,主线程在其他两个线程启动之前就结束了,这证明了尽管主线程是其他线程的父类,但线程的生命期是无关的。虽然,例中使用的进入点函数无关紧要,但其可调用它可访问的任意其他函数。 插1:三个线程的缠绕输出

上一页 1 2 3 4 下一页

评论   点击查看全部评论
您的评论参与,将为聚杰带来更大的动力!请不要吝啬!
快速回复
请使用文明语言让我们维护健康绿色网络环境!

匿名发表   验证码: