关闭

C++/CLR 中的多线程使用方法

标签: clr多线程
2126人阅读 评论(0) 收藏 举报
分类:

C++/CLR 中的多线程使用方法

本文由Monkey Man 撰写于 2015/7/10 0:41:33

在编写大型程序时,将所有任务都放在一条线程上来完成并不是一个明智的选择,因为程序一旦卡死在某个环节或是发生了死循环,整个程序都会废掉。所以适当的用多线程有利于程序的良好运行。

在C++/CLR中使用多线程是很方便的,以下介绍使用方法:

  • 添加命名空间using namespace System::Threading;

  • 创建新的线程Thread ^ oThread = gcnew Thread( gcnew ThreadStart( this, &data::df ));

  • 启动新的线程oThread->Start();

  • 关闭新的线程oThread->Abort(); 在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。 调用此方法通常会终止线程。

  • 挂起线程Thread::Sleep( n); n代表需要挂起的时间,单位为毫秒。哪个线程调用这个方法,哪个线程就挂起 n 毫秒。

    • This: 指当前的窗口句柄或指针。

    • &data::df: 你要在新进程里完成的任务。df 是data类中的一个函数。

一个例子:

    // [C++]
    //我用的编译环境是VS2010
    //使用/clr选项编译.
    using namespace System;
    using namespace System::Threading;

    // 简单的多线程示例:在第二个线程中运行
    //一个公有的方法 ThreadProc.
    public ref class ThreadExample
    {
    public:

       //在新线程中调用 ThreadProc 方法。
       //这个方法将会运行十次,每次都会向控制台输出一行文本,然后
       //挂起很短的一段时间。运行十次后结束运行。
       static void ThreadProc()
       {
          for ( int i = 0; i < 10; i++ )
          {
              Console::Write(  "ThreadProc: " );
              Console::WriteLine( i );

              // 把第二个线程挂起一段时间
              Thread::Sleep( 0 );
          }
       }   
    };

    int main()
    {
       Console::WriteLine( "主线程: 开启了第二个线程。" );
       //要说明的一点是,第一个线程就是当前 main() 函数所在的线程。

       // Create the thread, passing a ThreadStart delegate that
       // represents the ThreadExample::ThreadProc method.  For a 
       // delegate representing a static method, no object is
       // required.
       //这段我不会翻译,求看到这篇文章的大神赐教。
       //创建第二个线程。
       Thread^ oThread = gcnew Thread( gcnew ThreadStart(&ThreadExample::ThreadProc ) );

       // Start ThreadProc.  Note that on a uniprocessor, the new 
       // thread does not get any processor time until the main thread 
       // is preempted or yields.  Uncomment the Thread::Sleep that 
       // follows oThread->Start() to see the difference.
       //这段我也不会翻译,求看到这篇文章的大神赐教。
       //启动第二个线程
       oThread->Start();

       for ( int i = 0; i < 4; i++ )
       {
          Console::WriteLine(  "主线程: 做了些事情。" );
          //下面这个Thread::Sleep( 0 );的作用是把主线程挂起一段时间
          Thread::Sleep( 0 );

       }
       Console::WriteLine(  "主线程: 调用 Join(), 等待 ThreadProc 方法运行结束." );
       oThread->Join();
       Console::WriteLine(  "主线程: ThreadProc->Join() 已经返回控制权.  按任意键退出程序。" );
       Console::ReadLine();
       return 0;
    }

此代码产生的输出类似如下内容:

主线程: 开启了第二个线程。
主线程: 做了些事情。
ThreadProc: 0
ThreadProc: 1
ThreadProc: 2
ThreadProc: 3
ThreadProc: 主线程: 做了些事情。
主线程: 做了些事情。
主线程: 做了些事情。
4
ThreadProc: 5
ThreadProc: 6
ThreadProc: 7
ThreadProc: 8
ThreadProc: 9
主线程: 调用 Join(), 等待 ThreadProc 方法运行结束.
主线程: ThreadProc->Join() 已经返回控制权.  按任意键退出程序。

当然这里所呈现的结果并不唯一,运行时机器的状况和资源配置的状况会使主线程和第二条线程的运行情况发生变化。有时主线程会先运行完,然后等待第二个线程运行完;有时第二个线程会先运行完,然后主线程的输出跟在后面;也有可能两条线程的运行状况都差不多(比如上面那个示例输出。细心的人会发现第七行应该在同一行输出的 ThreadProc: 4 被拆到了第七行和第十行)。下面我们再看两组输出:

情况一:主线程会先运行完,然后等待第二个线程运行完

主线程: 开启了第二个线程。
主线程: 做了些事情。
主线程: 做了些事情。
主线程: 做了些事情。
主线程: 做了些事情。
主线程: 调用 Join(), 等待 ThreadProc 方法运行结束.
ThreadProc: 0
ThreadProc: 1
ThreadProc: 2
ThreadProc: 3
ThreadProc: 4
ThreadProc: 5
ThreadProc: 6
ThreadProc: 7
ThreadProc: 8
ThreadProc: 9
主线程: ThreadProc->Join() 已经返回控制权.  按任意键退出程序。

情况二:第二个线程先运行完,然后主线程的输出跟在后面

主线程: 开启了第二个线程。
主线程: 做了些事情。
ThreadProc: 0
ThreadProc: 1
ThreadProc: 2
ThreadProc: 3
ThreadProc: 4
ThreadProc: 5
ThreadProc: 6
ThreadProc: 7
ThreadProc: 8
ThreadProc: 9
主线程: 做了些事情。
主线程: 做了些事情。
主线程: 做了些事情。
主线程: 调用 Join(), 等待 ThreadProc 方法运行结束.
主线程: ThreadProc->Join() 已经返回控制权.  按任意键退出程序。

各位可以自己试一试,看看自己会产生那些运行结果(^ . ^)

参考:MSDN文档

1
0
查看评论

C多线程(三) -- CLR线程池的工作者线程

1. 关于CLR线程池使用ThreadStart与ParameterizedThreadStart建立新线程非常简单,但通过此方法建立的线程难于管理,若建立过多的线程反而会影响系统的性能所以,.NET引入CLR线程池这个概念。CLR线程池并不会在CLR初始化的时候立刻建立线程,而是在应用程序要创建线...
  • u011033906
  • u011033906
  • 2017-03-16 10:31
  • 460

快速入门系列--CLR--02多线程

最近,由于基础框架的整体升级,因此需要更新所有相关项目的DLL文件。这个过程存在不小的风险,因此也对发布后的生产服务器进行了密切的监控,结果还是出现了个别应用出现异常的情况,很快的占用了大量的服务器内存和CPU等资源。通过研究dump,初步发现是由于配置服务器出现单点故障,然后应用通过多线程调用相关...
  • e62ces0iem
  • e62ces0iem
  • 2017-06-14 14:40
  • 128

threadstart 一个参数和两个参数

threadstart 一个参数和两个参数,一个是静态执行,一个是实例执行 Visual C++ using namespace System; using namespace System::Threading; ref class Work { public: stati...
  • qq1987924
  • qq1987924
  • 2013-10-23 10:29
  • 1793

CLI/C++中混合类的使用

CLI/C++中混合类的使用 一 混合类 所谓混合类是指CLI/C++中native的Class中可以包含CLR对象,CLR的class也可以包含Naitve的对象。 1)native的class中包含CLR对象,必须通过gcroot。 2)CLR中的class中包含native...
  • jfkidear
  • jfkidear
  • 2014-01-17 10:16
  • 1342

VS2008中关于编译是/clr的相关错误。

<br /> “/clr”是新版本的VC++才有的选项,目的是让C++可以调用微软.NET中的功能。而C语言是不能调用.NET的,所以出错。<br /> 解 决方法是把/clr选项去掉。具体的做法是:在你的工程上点鼠标右键,选择最后一项“...
  • tianyi_lee
  • tianyi_lee
  • 2010-08-05 10:09
  • 1379

C++11的线程库(一)

个人认为C++11最明智的举动之一就是加入了线程库,在多核CPU越来越普及,在多线程编程日益,我们可以说是”疯狂“的时代,一个不支持多线程(我是指本身不支持,在编程过程中需要依赖线程库)的语言,如何能普遍适用? 在C++11之前在C/C++中使用多线程编程并非鲜见,这样的代码主要是使用POSIX线...
  • charles_r_chiu
  • charles_r_chiu
  • 2015-05-27 17:24
  • 2941

C++中gcnew()

在VS2010中可能是因为.net是对C++又进行了优化。有些代码不同了,现记录于此,防止以后忘掉了。 StreamWriter^ sw = File::CreateText(path); 上面的^可能就是引用的意思,就是原来C++中的指针了。 sw->WriteLine( ...
  • shandiantianying
  • shandiantianying
  • 2013-08-05 17:35
  • 4497

Thread.SetData 方法

Thread.SetData 方法在当前正在运行的线程上为此线程的当前域在指定槽中设置数据。 命名空间:System.Threading程序集:mscorlib(在 mscorlib.dll 中)  语法 C#public static void SetData ( LocalDat...
  • jiangxinyu
  • jiangxinyu
  • 2008-04-09 14:51
  • 2051

C++/CLR 概念原理

一、CLI简介   CLI:(Common Language Infrastructure,通用语言框架)提供了一套可执行代码和它所运行需要的虚拟执行环境的规范。更通俗的我们可以说它是一个虚拟平台,是操作系统和应用程序间的一层抽象。微软的.NET的基础CLR(Common Language...
  • zxxSsdsd
  • zxxSsdsd
  • 2013-07-16 15:14
  • 1463

《CLR via C#:框架设计》读书笔记 - CLR寄宿和AppDomain

《CLR via C#:框架设计》读书笔记 - CLR寄宿和AppDomain
  • a2324268086
  • a2324268086
  • 2016-04-22 00:40
  • 586
    个人资料
    • 访问:2761次
    • 积分:71
    • 等级:
    • 排名:千里之外
    • 原创:1篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档