科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件实例解析C++/CLI线程之线程状态持久性

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

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

作者:谢启东编译 来源:天极开发 2007年11月14日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
原子性与互锁操作

  如果存在这样一种情况:一个应用程序有多个线程并行运行,每个线程对某些共享的整形变量,都有写操作--只是简单地使用++把变量递增1。这看起来似乎没什么问题,毕竟,还算像是一个原子性操作,但在多数系统中--至少从机器指令的角度来看,C++/CLI执行环境对所有整形类型,并不能普遍地保证无误。

  作为示例,例4中的程序有三个线程,每个线程都同时递增一个共享的64位整形变量一千万次,最后显示出这个变量的最终值,从理论上说,应该共递增了三千万次。这个程序目前可以两种方式运行:默认方式使用++操作符以非同步方式运行;而另一种方式,通过带有命令行参数Y或y,这回使用了一个同步的库递增函数。

  例4:

using namespace System;
using namespace System::Threading;

static bool interlocked = false;
const int maxCount = 10000000;
/*1*/ static long long value = 0;

void TMain()
{
 if (interlocked)
 {
  for (int i = 1; i <= maxCount; ++i)
  {
   /*2*/ Interlocked::Increment(value);
  }
 }
 else
 {
  for (int i = 1; i <= maxCount; ++i)
  {
   /*3*/ ++value;
  }
 }
}

int main(array<String^>^ argv)
{
 if (argv->Length == 1)
 {
  if (argv[0]->Equals("Y") || argv[0]->Equals("y"))
  {
   interlocked = true;
  }
 }

 /*4*/ Thread^ t1 = gcnew Thread(gcnew ThreadStart(&TMain));
 Thread^ t2 = gcnew Thread(gcnew ThreadStart(&TMain));
 Thread^ t3 = gcnew Thread(gcnew ThreadStart(&TMain));

 t1->Start();
 t2->Start();
 t3->Start();
 t1->Join();
 t2->Join();
 t3->Join();

 Console::WriteLine("After {0} operations, value = {1}", 3 * maxCount, value);
}

  当使用标准++操作符时,程序5次连续执行之后,输出如插3所示,可看出,结果与正确答案相距甚远,简单估算,大概有17%至50%的递增操作未正确完成;当程序运行于同步方式时--即使用Interlocked::Increment,所有的三千万次递增操作都正常完成,结果计算正确。

  插3:

  使用++操作符的输出

After 30000000 operations, value = 14323443
After 30000000 operations, value = 24521969
After 30000000 operations, value = 20000000
After 30000000 operations, value = 24245882
After 30000000 operations, value = 25404963

  使用Interlocked递增函数的输出

After 30000000 operations, value = 30000000

  另外,补充一点,Interlocked类还有另一个decrement函数。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章