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");
}
一 简单实例(来自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");
}
发表评论
-
字节对齐
2009-09-11 15:27 764本文主要包括二个部分 ... -
到底什么时候用指针
2009-06-08 10:33 2318在c/c++编程中,到底什么时候该用指针来传递参数呢?总结如下 ... -
IP组播的地址映射分析
2008-11-22 12:58 3740IP组播地址,23对于MAC23位,是怎么换算的? ... -
http://www.java3z.com/cwbwebhome/article/article2a
2008-10-31 21:13 8961.位图的理解 我们都明白图形格式中位图储存方式,其 ... -
http://blog.csdn.net/qw_study/arc
2008-10-31 21:03 1073基本思想: 定义一个带排序数中的最大数为DataForSto ... -
字符常量区
2008-10-23 20:26 1369最近写C常常遇到STATUS_ACCESS_VIOLATION ... -
线程函数
2008-10-23 19:40 820在c++中写多线程程序时候,经常出现: error C2 ... -
关于临界区问题的分析
2008-09-27 22:06 1616比如说我们定义了一个 ... -
http://fevair.itpub.net/post/23540/212646
2008-09-27 21:26 888程序员对于Windows程序中 ... -
位图算法-找中值
2008-09-22 19:25 1898// // Sample for vector arithme ... -
学习札记:使用const 提高函数的健壮性
2008-09-19 11:37 85411.1 使用const 提高函数的健壮性 看到const 关 ... -
深入理解sizeof
2008-09-18 09:30 806最近在论坛里总有人问关于sizeof的问题,并且本人对这个问题 ...
相关推荐
总结来说,这个“最简单的C++线程封装”示例展示了如何通过面向对象的方式创建跨平台的线程类,提供了一致的接口供用户实现线程逻辑,并处理了不同操作系统的线程创建、同步和管理细节。这对于开发跨平台的C++应用...
C++线程库介绍 C++线程库是C++11标准库中的一部分,提供了对线程的支持,包括线程创建、互斥量、条件变量、future等。下面是一些重要的知识点: 1. 线程库概览 C++11引入了一个新的线程库,提供了对线程的支持。...
《C++线程树_v0.01》项目是一个实现线程树结构的自定义类库,主要用于在GUI环境中,特别是在使用LISTVIEW组件时进行高效重绘操作。在这个项目中,我们可以看到一系列与多线程编程相关的源代码文件,如...
在C++编程中,多线程技术是一种常见且强大的并发执行方式,特别是在处理大量数据、实时计算或异步任务时。Visual Studio 2019 提供了对C++11标准库的支持,其中包含了对多线程编程的API。在本项目"线程暂停、继续"中...
visual studio C++线程同步
在C++编程中,线程(Thread)是并发执行的代码段,允许程序在同一时间处理多个任务。将线程函数定义为类的成员函数是一种常见的做法,它有助于封装相关数据和行为,使得代码更加模块化和易于管理。下面我们将详细...
内容概要:文章内容从原子性、可见性、有序性三个方面介绍C++线程安全问题的原因。通过原子操作、线程同步如互斥锁、读写锁、条件变量、信号量等方法解决C++线程安全问题。同时介绍了线程安全的单例,饿汉模式和懒汉...
本学习笔记主要涵盖了C++中的几个关键主题:线程、指针、调试以及编码实践。 首先,关于C++的线程:在多核处理器的时代,线程成为了实现并行处理和提高程序性能的重要手段。C++11引入了标准库中的`<thread>`,使得...
在"C++线程测试3!"这个主题中,我们可能是在探讨如何利用C++标准库中的线程支持进行多线程编程。下面我们将详细讲解相关的C++线程知识。 C++11引入了对线程的支持,这使得程序员可以更容易地编写多线程程序。在C++...
本篇将深入探讨C++线程的相关知识,并通过代码实例帮助初学者理解其工作原理。 C++11标准引入了内置的线程支持库`<thread>`,这使得创建和管理线程变得更加简单。下面我们将介绍几个关键的概念: 1. **线程创建**...
【C++ 语言】线程安全队列 ( 条件变量 | 线程调度 ) : https://hanshuliang.blog.csdn.net/article/details/102851323 下载完项目后 , 使用 Visual Studio 打开 , 注意需要配置 POSIX 线程库 ( 参考以下博客配置...
C++线程测试文件主要涉及的是C++11及更高版本中引入的多线程编程概念,这是一个在现代计算机科学中至关重要的主题。C++线程库允许开发者创建和管理并发执行的任务,从而充分利用多核处理器的优势,提高程序的执行...
C++线程钩子代码是程序开发中一种高级技术,主要用于在多线程环境中实现对特定线程行为的监控、调试或干预。线程钩子是Windows API提供的一种功能,允许程序员插入自定义代码到系统调用流程中,以便在特定时刻执行...
本文将详细解析标题为“Linux C/C++线程基类源代码”的项目,该基类封装了创建和管理线程的关键操作,方便开发者直接继承和使用。 首先,我们来看`Thread.h`头文件。这个文件通常会定义一个名为`Thread`的基类,它...
以下是一些关于C++线程创建和调用的关键知识点: 1. **线程创建**:在C++中,创建一个新线程可以通过`std::thread`类来实现。首先,定义一个函数,这个函数将在新线程中运行。例如,我们可以有一个名为`...
本教程将深入探讨C++线程的常用操作,包括创建线程、线程同步、线程通信以及线程管理。 1. **线程创建** - `std::thread`构造函数:创建新线程时,你需要传递一个函数或成员函数指针以及其参数。例如,`std::...
linux c++线程demo
创建一个C++线程的基本步骤包括: 1. **包含头文件**:引入`<thread>`头文件,这将提供创建和管理线程所需的所有功能。 2. **定义线程函数**:线程函数是一个返回类型为`void`的函数,它接受一个可选参数,这个函数...
"C++线程安全日志库"是专门为C++编程语言设计的一种库,它允许程序员在多线程程序中安全地记录日志信息,同时提供了丰富的配置选项来满足不同需求。 线程安全是这个日志库的核心特性,这意味着当多个线程同时写入...
"C++线程加锁" C++线程加锁是指在多线程编程中,使用锁机制来保护共享资源的安全访问。锁机制可以防止多个线程同时访问共享资源,避免了数据的不一致和崩溃。 Win32 提供的临界区(Critical Section)可以方便地...