`
hitqiang
  • 浏览: 36136 次
  • 性别: Icon_minigender_1
  • 来自: shangdpng
最近访客 更多访客>>
社区版块
存档分类
最新评论

c++线程

阅读更多
C/C++ Runtime 多线程函数

一 简单实例(来自codeprojct:http://www.codeproject.com/useritems/MultithreadingTutorial.asp)
主线程创建2个线程t1和t2,创建时2个线程就被挂起,后来调用ResumeThread恢复2个线程,是其开始执行,调用WaitForSingleObject等待2个线程执行完,然后推出主线程即结束进程。

/**//*  file Main.cpp
*
*  This program is an adaptation of the code Rex Jaeschke showed in
*  Listing 1 of his Oct 2005 C/C++ User's Journal article entitled
*  "C++/CLI Threading: Part I".  I changed it from C++/CLI (managed)
*  code to standard C++.
*
*  One hassle is the fact that C++ must employ a free (C) function
*  or a static class member function as the thread entry function.
*
*  This program must be compiled with a multi-threaded C run-time
*  (/MT for LIBCMT.LIB in a release build or /MTd for LIBCMTD.LIB
*  in a debug build).
*
*                                      John Kopplin  7/2006
*/


#include <stdio.h>
#include <string>             // for STL string class
#include <windows.h>          // for HANDLE
#include <process.h>          // for _beginthread()

using namespace std;


class ThreadX
{
private:
  int loopStart;
  int loopEnd;
  int dispFrequency;

public:
  string threadName;

  ThreadX( int startValue, int endValue, int frequency )
  {
    loopStart = startValue;
    loopEnd = endValue;
    dispFrequency = frequency;
  }

  // In C++ you must employ a free (C) function or a static
  // class member function as the thread entry-point-function.
  // Furthermore, _beginthreadex() demands that the thread
  // entry function signature take a single (void*) and returned
  // an unsigned.
  static unsigned __stdcall ThreadStaticEntryPoint(void * pThis)
  {
      ThreadX * pthX = (ThreadX*)pThis;   // the tricky cast
      pthX->ThreadEntryPoint();           // now call the true entry-point-function

      // A thread terminates automatically if it completes execution,
      // or it can terminate itself with a call to _endthread().

      return 1;          // the thread exit code
  }

  void ThreadEntryPoint()
  {
     // This is the desired entry-point-function but to get
     // here we have to use a 2 step procedure involving
     // the ThreadStaticEntryPoint() function.

    for (int i = loopStart; i <= loopEnd; ++i)
    {
      if (i % dispFrequency == 0)
      {
          printf( "%s: i = %d\n", threadName.c_str(), i );
      }
    }
    printf( "%s thread terminating\n", threadName.c_str() );
  }
};


int main()
{
    // All processes get a primary thread automatically. This primary
    // thread can generate additional threads.  In this program the
    // primary thread creates 2 additional threads and all 3 threads
    // then run simultaneously without any synchronization.  No data
    // is shared between the threads.

    // We instantiate an object of the ThreadX class. Next we will
    // create a thread and specify that the thread is to begin executing
    // the function ThreadEntryPoint() on object o1. Once started,
    // this thread will execute until that function terminates or
    // until the overall process terminates.

    ThreadX * o1 = new ThreadX( 0, 1, 2000 );

    // When developing a multithreaded WIN32-based application with
    // Visual C++, you need to use the CRT thread functions to create
    // any threads that call CRT functions. Hence to create and terminate
    // threads, use _beginthreadex() and _endthreadex() instead of
    // the Win32 APIs CreateThread() and EndThread().

    // The multithread library LIBCMT.LIB includes the _beginthread()
    // and _endthread() functions. The _beginthread() function performs
    // initialization without which many C run-time functions will fail.
    // You must use _beginthread() instead of CreateThread() in C programs
    // built with LIBCMT.LIB if you intend to call C run-time functions.

    // Unlike the thread handle returned by _beginthread(), the thread handle
    // returned by _beginthreadex() can be used with the synchronization APIs.

    HANDLE   hth1;
    unsigned  uiThread1ID;

    hth1 = (HANDLE)_beginthreadex( NULL,         // security
                                   0,            // stack size
                                   ThreadX::ThreadStaticEntryPoint,
                                   o1,           // arg list
                                   CREATE_SUSPENDED,  // so we can later call ResumeThread()
                                   &uiThread1ID );

    if ( hth1 == 0 )
        printf("Failed to create thread 1\n");

    DWORD   dwExitCode;

    GetExitCodeThread( hth1, &dwExitCode );  // should be STILL_ACTIVE = 0x00000103 = 259
    printf( "initial thread 1 exit code = %u\n", dwExitCode );

    // The System::Threading::Thread object in C++/CLI has a "Name" property.
    // To create the equivalent functionality in C++ I added a public data member
    // named threadName.

    o1->threadName = "t1";

    ThreadX * o2 = new ThreadX( -1000000, 0, 2000 );

    HANDLE   hth2;
    unsigned  uiThread2ID;

    hth2 = (HANDLE)_beginthreadex( NULL,         // security
                                   0,            // stack size
                                   ThreadX::ThreadStaticEntryPoint,
                                   o2,           // arg list
                                   CREATE_SUSPENDED,  // so we can later call ResumeThread()
                                   &uiThread2ID );

    if ( hth2 == 0 )
        printf("Failed to create thread 2\n");

    GetExitCodeThread( hth2, &dwExitCode );  // should be STILL_ACTIVE = 0x00000103 = 259
    printf( "initial thread 2 exit code = %u\n", dwExitCode );

    o2->threadName = "t2";

    // If we hadn't specified CREATE_SUSPENDED in the call to _beginthreadex()
    // we wouldn't now need to call ResumeThread().

    ResumeThread( hth1 );   // serves the purpose of Jaeschke's t1->Start()

    ResumeThread( hth2 );

    // In C++/CLI the process continues until the last thread exits.
    // That is, the thread's have independent lifetimes. Hence
    // Jaeschke's original code was designed to show that the primary
    // thread could exit and not influence the other threads.

    // However in C++ the process terminates when the primary thread exits
    // and when the process terminates all its threads are then terminated.
    // Hence if you comment out the following waits, the non-primary
    // threads will never get a chance to run.

    WaitForSingleObject( hth1, INFINITE );
    WaitForSingleObject( hth2, INFINITE );

    GetExitCodeThread( hth1, &dwExitCode );
    printf( "thread 1 exited with code %u\n", dwExitCode );

    GetExitCodeThread( hth2, &dwExitCode );
    printf( "thread 2 exited with code %u\n", dwExitCode );

    // The handle returned by _beginthreadex() has to be closed
    // by the caller of _beginthreadex().

    CloseHandle( hth1 );
    CloseHandle( hth2 );

    delete o1;
    o1 = NULL;

    delete o2;
    o2 = NULL;

    printf("Primary thread terminating.\n");
}
分享到:
评论

相关推荐

    最简单的C++ 线程封装

    总结来说,这个“最简单的C++线程封装”示例展示了如何通过面向对象的方式创建跨平台的线程类,提供了一致的接口供用户实现线程逻辑,并处理了不同操作系统的线程创建、同步和管理细节。这对于开发跨平台的C++应用...

    C++线程库介绍

    C++线程库介绍 C++线程库是C++11标准库中的一部分,提供了对线程的支持,包括线程创建、互斥量、条件变量、future等。下面是一些重要的知识点: 1. 线程库概览 C++11引入了一个新的线程库,提供了对线程的支持。...

    C++线程树_v0.01

    《C++线程树_v0.01》项目是一个实现线程树结构的自定义类库,主要用于在GUI环境中,特别是在使用LISTVIEW组件时进行高效重绘操作。在这个项目中,我们可以看到一系列与多线程编程相关的源代码文件,如...

    C++ 线程暂停、继续

    在C++编程中,多线程技术是一种常见且强大的并发执行方式,特别是在处理大量数据、实时计算或异步任务时。Visual Studio 2019 提供了对C++11标准库的支持,其中包含了对多线程编程的API。在本项目"线程暂停、继续"中...

    visual studio C++线程同步

    visual studio C++线程同步

    C++ 线程函数是类的成员函数

    在C++编程中,线程(Thread)是并发执行的代码段,允许程序在同一时间处理多个任务。将线程函数定义为类的成员函数是一种常见的做法,它有助于封装相关数据和行为,使得代码更加模块化和易于管理。下面我们将详细...

    C++线程安全问题及解决方法,C++智能指针

    内容概要:文章内容从原子性、可见性、有序性三个方面介绍C++线程安全问题的原因。通过原子操作、线程同步如互斥锁、读写锁、条件变量、信号量等方法解决C++线程安全问题。同时介绍了线程安全的单例,饿汉模式和懒汉...

    c++学习笔记(c++ 线程 指针 调试 编码)

    本学习笔记主要涵盖了C++中的几个关键主题:线程、指针、调试以及编码实践。 首先,关于C++的线程:在多核处理器的时代,线程成为了实现并行处理和提高程序性能的重要手段。C++11引入了标准库中的`&lt;thread&gt;`,使得...

    C++线程测试3!

    在"C++线程测试3!"这个主题中,我们可能是在探讨如何利用C++标准库中的线程支持进行多线程编程。下面我们将详细讲解相关的C++线程知识。 C++11引入了对线程的支持,这使得程序员可以更容易地编写多线程程序。在C++...

    C++线程实例_C++_线程_

    本篇将深入探讨C++线程的相关知识,并通过代码实例帮助初学者理解其工作原理。 C++11标准引入了内置的线程支持库`&lt;thread&gt;`,这使得创建和管理线程变得更加简单。下面我们将介绍几个关键的概念: 1. **线程创建**...

    C++线程安全队列_示例代码.zip

    【C++ 语言】线程安全队列 ( 条件变量 | 线程调度 ) : https://hanshuliang.blog.csdn.net/article/details/102851323 下载完项目后 , 使用 Visual Studio 打开 , 注意需要配置 POSIX 线程库 ( 参考以下博客配置...

    c++线程测试文件

    C++线程测试文件主要涉及的是C++11及更高版本中引入的多线程编程概念,这是一个在现代计算机科学中至关重要的主题。C++线程库允许开发者创建和管理并发执行的任务,从而充分利用多核处理器的优势,提高程序的执行...

    C++ 线程钩子代码

    C++线程钩子代码是程序开发中一种高级技术,主要用于在多线程环境中实现对特定线程行为的监控、调试或干预。线程钩子是Windows API提供的一种功能,允许程序员插入自定义代码到系统调用流程中,以便在特定时刻执行...

    Linux C/C++线程基类源代码

    本文将详细解析标题为“Linux C/C++线程基类源代码”的项目,该基类封装了创建和管理线程的关键操作,方便开发者直接继承和使用。 首先,我们来看`Thread.h`头文件。这个文件通常会定义一个名为`Thread`的基类,它...

    C++ 线程的创建与调用

    以下是一些关于C++线程创建和调用的关键知识点: 1. **线程创建**:在C++中,创建一个新线程可以通过`std::thread`类来实现。首先,定义一个函数,这个函数将在新线程中运行。例如,我们可以有一个名为`...

    C++ 线程学习,thread常用操作

    本教程将深入探讨C++线程的常用操作,包括创建线程、线程同步、线程通信以及线程管理。 1. **线程创建** - `std::thread`构造函数:创建新线程时,你需要传递一个函数或成员函数指针以及其参数。例如,`std::...

    linux c++线程demo

    linux c++线程demo

    c++实现多线程同步

    创建一个C++线程的基本步骤包括: 1. **包含头文件**:引入`&lt;thread&gt;`头文件,这将提供创建和管理线程所需的所有功能。 2. **定义线程函数**:线程函数是一个返回类型为`void`的函数,它接受一个可选参数,这个函数...

    C++线程安全日志库

    "C++线程安全日志库"是专门为C++编程语言设计的一种库,它允许程序员在多线程程序中安全地记录日志信息,同时提供了丰富的配置选项来满足不同需求。 线程安全是这个日志库的核心特性,这意味着当多个线程同时写入...

    c++线程加锁.pdf

    "C++线程加锁" C++线程加锁是指在多线程编程中,使用锁机制来保护共享资源的安全访问。锁机制可以防止多个线程同时访问共享资源,避免了数据的不一致和崩溃。 Win32 提供的临界区(Critical Section)可以方便地...

Global site tag (gtag.js) - Google Analytics