新客网
首页 | 新闻 | 系统·网络·服务器·安全 | 工具·办公 | 编程·数据库 | 图象·网页·运营 | 硬件·存储 | 专题教程 | 旧版
 → 当前位置:首页 > 教程 > 编程开发 > C/C#/C++ > 正文

实例解析C++/CLI线程之线程状态持久性

XKER.COM   2006-9-23 10:23:17  来源:天极开发  点击:

  其他形式的同步

  我们可使用类Monitor与类Thread中的某些函数,直接控制线程的同步,请看例1。

  例1:

using namespace System;
using namespace System::Threading;

int main()
{
 /*1*/ MessageBuffer^ m = gcnew MessageBuffer;

 /*2a*/ ProcessMessages^ pm = gcnew ProcessMessages(m);
 /*2b*/ Thread^ pmt = gcnew Thread(gcnew ThreadStart(pm,&ProcessMessages::ProcessMessagesEntryPoint));
 /*2c*/ pmt->Start();

 /*3a*/ CreateMessages^ cm = gcnew CreateMessages(m);
 /*3b*/ Thread^ cmt = gcnew Thread(gcnew ThreadStart(cm, &CreateMessages::CreateMessagesEntryPoint));
 /*3c*/ cmt->Start();

 /*4*/ cmt->Join();
 /*5*/ pmt->Interrupt();
 /*6*/ pmt->Join();

 Console::WriteLine("Primary thread terminating");
}

public ref class MessageBuffer
{
 String^ messageText;
 public:
  void SetMessage(String^ s)
  {
   /*7*/ Monitor::Enter(this);
   messageText = s;
   /*8*/ Monitor::Pulse(this);
   Console::WriteLine("Set new message {0}", messageText);
   Monitor::Exit(this);
  }

  void ProcessMessages()
  {
   /*9*/ Monitor::Enter(this);
   while (true)
   {
    try
    {
     /*10*/ Monitor::Wait(this);
    }
    catch (ThreadInterruptedException^ e)
    {
     Console::WriteLine("ProcessMessage interrupted");
     return;
    }

    Console::WriteLine("Processed new message {0}", messageText);
   }
   Monitor::Exit(this);
  }
};

public ref class CreateMessages
{
 MessageBuffer^ msg;
 public:
  CreateMessages(MessageBuffer^ m)
  {
   msg = m;
  }

  void CreateMessagesEntryPoint()
  {
   for (int i = 1; i <= 5; ++i)
   {
    msg->SetMessage(String::Concat("M-", i.ToString()));
    Thread::Sleep(2000);
   }
   Console::WriteLine("CreateMessages thread terminating");
  }
};

public ref class ProcessMessages
{
 MessageBuffer^ msg;
 public:
  ProcessMessages(MessageBuffer^ m)
  {
   msg = m;
  }

  void ProcessMessagesEntryPoint()
  {
   msg->ProcessMessages();
   Console::WriteLine("ProcessMessages thread terminating");
  }
};

  在标记1中,创建一个MessageBuffer类型的共享缓冲区;接着在标记2a、2b、2c中,创建了一个线程用于处理放置于缓冲区中的每条信息;标记3a、3b和3c,也创建了一个线程,并在共享缓冲区中放置了连续的5条信息以便处理。这两个线程已被同步,因此处理者线程必须等到有"东西"放入到缓冲区中,才可以进行处理,且在前一条信息被处理完之前,不能放入第二条信息。在标记4中,将一直等待,直到创建者线程完成它的工作。

  当标记5执行时,处理者线程必须处理所有创建者线程放入的信息,因为使用了Thread::Interrupt让其停止工作,并继续等待标记6中调用的Thread::Join,这个函数允许调用线程阻塞它自己,直到其他线程结束。(一个线程可指定一个等待的最大时间,而不用无限等待下去。)

  线程CreateMessages非常清晰明了,它向共享缓冲区中写入了5条信息,并在每条信息之间等待2秒。为把一个线程挂起一个给定的时间(以毫秒计),我们调用了Thread::Sleep,在此,一个睡眠的线程可再继续执行,原因在于运行时环境,而不是另一个线程。

  线程ProcessMessages甚至更加简单,因为它利用了类MessageBuffer来做它的所有工作。类MessageBuffer中的函数是被同步的,因此在同一时间,只有一个函数能访问共享缓冲区。

  主程序首先启动处理者线程,这个线程会执行ProcessMessages,其将获得父对象的同步锁;然而,它立即调用了标记10中的Wait函数,这个函数将让它一直等待,直到再次被告之运行,期间,它也交出了同步锁,这样,允许创建者线程得到同步锁并执行SetMessage。一旦函数把新的信息放入到共享缓冲区中,就会调用标记8中的Pulse,其允许等待同步锁的任意线程被唤醒,并继续执行下去。但是,在SetMessage执行完成之前,这些都不可能发生,因为它在函数返回前都不可能交出同步锁。如果情况一旦发生,处理者线程将重新得到同步锁,并从标记10之后开始继续执行。此处要说明的是,一个线程即可无限等待,也可等到一个指定的时间到达。插1是程序的输出。

  插1:

Set new message M-1
Processed new message M-1
Set new message M-2
Processed new message M-2
Set new message M-3
Processed new message M-3
Set new message M-4
Processed new message M-4
Set new message M-5
Processed new message M-5
CreateMessages thread terminating
ProcessMessage interrupted
ProcessMessages thread terminating
Primary thread terminating

  请仔细留意,处理者线程启动于创建者线程之前。如果以相反的顺序启动,将会在没有处理者线程等待的情况下,添加第一条信息,此时,没有可供唤醒处理者线程,当处理者线程运行到它的第一个函数调用Wait时,将会错过第一条信息,且只会在第二条信息存储时被唤醒。

本新闻共3页,当前在第1页  1  2  3  

上一篇教程:在Visual C#.Net中使用CWGraph控件
下一篇教程:用C#通过网址得到域名
收藏本文】 【我要投稿】 【打印本文】 【论坛讨论】 【关闭窗口

相关文章
·C++中class与struct的区别·Visual C++2005中开发自定义绘图控件
·Visual C++实现WinXP关机特效·VC++中利用/GS开关防止缓冲区溢出
·C++中要求(或禁止)对象产生于heap中·致Delphi和C++Builder社群的一封公开信
·C++:最强大的.NET语言之对象构造·C++:最强大的.NET语言之内存与资源
·在Eclipse中集成Ant编程之配置祥解篇·C++数据类型的属性与限制
·Visual C++2005中开发自定义绘图控件·C++的未来之路:C++0x概览
·C++/CLI思辨录之代理构造函数·C++的救赎 C++开源程序库评话
·C++多态技术的实现和反思·保持C/C++程序代码可伸缩性

学院文章搜索
  
推荐文章
·编程过把瘾:自己动手写操
·数据恢复指南 专题
·硬盘“逻辑锁”解决办法
·DOS使用中的常见问题解答
·DOS下常用的相关网络命令
·Win2000优化技巧篇之:硬件
·惊心8小时:破译Windows运行
·菜鸟必备:超实用低级格式
·硬件有价数据无价 硬盘开盘
·国内数据恢复市场内幕揭秘
阅读排行
·免费代理IP(每日更新)
·DB2 9数据库专题
·关于 Apache 的几种常见应
·QQ千人好友浮出水面 会员抢
·站长手册:WIN2003下Web服
·佳能活动 免费得QQ秀
·网站投资你和我的20个自身
·140天,从做站起步到日赚1
·Fdisk分区详解
·超强公式编辑器MathType使
专题教程
·数据恢复指南 专题
·Web服务器专题
·DB2 9数据库专题
·ghost教程 专题
·局域网技术专题
·虚拟机专题
·CDN加速技术专题
·注册表教程专题
·电脑技巧 专题
·Linux与虚拟化技术
最新文章
·Firefox出现新高危0Day漏洞
·QQ千人好友浮出水面 会员抢
·DOS下对系统重新进行分区
·Fdisk分区详解
·DOS常用命令
·dos如何进行系统配置
·dos慎用命令
·Ver、Vol、Ctty命令使用说
·Tree、Unformat、Vsafe命令
·Setver、Share、Subst命令
设为首页 - 加入收藏 - 版权声明 - 广告服务 - 关于我们 - 联系我们 - 友情连接
Copyright © 2003 - 2006 XKER Inc. All Rights Reserved
新客网 版权所有