我正在尝试用C ++(Win32)创建一个线程来运行一个简单的方法。我是C ++线程的新手,但对C#中的线程非常熟悉。这是我正在尝试做的一些伪代码:
static void MyMethod(int data)
{
RunStuff(data);
}
void RunStuff(int data)
{
//long running operation here
}
我想从 MyMethod 调用 RunStuff 而不阻止它。在单独的线程上运行 RunStuff 的最简单方法是什么?
编辑:我还应该提一下,我希望将依赖项保持在最低限度。 (没有MFC ......等)
答案 0 :(得分:13)
#include <boost/thread.hpp>
static boost::thread runStuffThread;
static void MyMethod(int data)
{
runStuffThread = boost::thread(boost::bind(RunStuff, data));
}
// elsewhere...
runStuffThread.join(); //blocks
答案 1 :(得分:7)
C ++ 11与更新的编译器(如Visual Studio 2013)一起提供,其中包含线程作为语言的一部分以及其他一些非常好的部分,例如lambdas。
包含文件threads
提供了一组线程类,它是一组模板。线程功能位于std::
命名空间中。一些线程同步函数使用std::this_thread
作为命名空间(有关解释,请参阅Why the std::this_thread namespace?)。
使用Visual Studio 2013的以下控制台应用程序示例演示了C ++ 11的一些线程功能,包括使用lambda(请参阅What is a lambda expression in C++11?)。请注意,用于线程休眠的函数(例如std::this_thread::sleep_for()
)使用std::chrono
的持续时间。
// threading.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
int funThread(const char *pName, const int nTimes, std::mutex *myMutex)
{
// loop the specified number of times each time waiting a second.
// we are using this mutex, which is shared by the threads to
// synchronize and allow only one thread at a time to to output.
for (int i = 0; i < nTimes; i++) {
myMutex->lock();
std::cout << "thread " << pName << " i = " << i << std::endl;
// delay this thread that is running for a second.
// the this_thread construct allows us access to several different
// functions such as sleep_for() and yield(). we do the sleep
// before doing the unlock() to demo how the lock/unlock works.
std::this_thread::sleep_for(std::chrono::seconds(1));
myMutex->unlock();
std::this_thread::yield();
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
// create a mutex which we are going to use to synchronize output
// between the two threads.
std::mutex myMutex;
// create and start two threads each with a different name and a
// different number of iterations. we provide the mutex we are using
// to synchronize the two threads.
std::thread myThread1(funThread, "one", 5, &myMutex);
std::thread myThread2(funThread, "two", 15, &myMutex);
// wait for our two threads to finish.
myThread1.join();
myThread2.join();
auto fun = [](int x) {for (int i = 0; i < x; i++) { std::cout << "lambda thread " << i << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); } };
// create a thread from the lambda above requesting three iterations.
std::thread xThread(fun, 3);
xThread.join();
return 0;
}
答案 2 :(得分:4)
CreateThread (Win32)和AfxBeginThread (MFC)是两种方法。
无论哪种方式,你的MyMethod签名都需要改变一下。
编辑:如评论和其他受访者所述,CreateThread可能不好。
_beginthread and _beginthreadex是C运行时库函数,根据文档等同于System::Threading::Thread::Start
答案 3 :(得分:3)
考虑使用Win32线程池,而不是为工作项启动新线程。旋转新线程是浪费的 - 默认情况下,每个线程为其堆栈获取1 MB的保留地址空间,运行系统的线程启动代码,导致通知几乎传递到进程中的每个DLL,并创建另一个内核对象。线程池使您能够快速有效地重用线程以执行后台任务,并根据您提交的任务数量增加或缩小。一般来说,考虑为永不停止的后台任务启动专用线程,并将线程池用于其他所有事务。
在Vista之前,您可以使用QueueUserWorkItem。在Vista上,新的线程池API更可靠,并提供了一些更高级的选项。每个都会导致您的后台代码开始在某个线程池线程上运行。
// Vista
VOID CALLBACK MyWorkerFunction(PTP_CALLBACK_INSTANCE instance, PVOID context);
// Returns true on success.
TrySubmitThreadpoolCallback(MyWorkerFunction, context, NULL);
// Pre-Vista
DWORD WINAPI MyWorkerFunction(PVOID context);
// Returns true on success
QueueUserWorkItem(MyWorkerFunction, context, WT_EXECUTEDEFAULT);
答案 4 :(得分:2)
C ++中的简单线程是一个矛盾!
查看提升线程,了解最接近现有的简单方法。
对于最小答案(实际上并不能为您提供同步所需的所有内容,而是直接回答您的问题),请参阅:
http://msdn.microsoft.com/en-us/library/kdzttdcb(VS.80).aspx
同样static
表示C ++中的不同内容。
答案 5 :(得分:1)
这是安全的吗?
unsigned __stdcall myThread(void *ArgList) {
//Do stuff here
}
_beginthread(myThread, 0, &data);
在此次通话后,我是否需要做任何事情来释放内存(如CloseHandle)?
答案 6 :(得分:1)
另一种选择是pthreads - 它们适用于Windows和Linux!
答案 7 :(得分:0)
CreateThread(Win32)和AfxBeginThread(MFC)是两种方法。
如果您需要使用C运行时库(CRT),请小心使用_beginthread。
答案 8 :(得分:0)
仅适用于win32且无需其他库即可使用 CreateThread函数 http://msdn.microsoft.com/en-us/library/ms682453(VS.85).aspx
答案 9 :(得分:0)
如果你真的不想使用第三方库(我建议使用boost :: thread,如其他的anwsers中所述),你需要使用Win32API:
static void MyMethod(int data)
{
int data = 3;
HANDLE hThread = ::CreateThread(NULL,
0,
&RunStuff,
reinterpret_cast<LPVOID>(data),
0,
NULL);
// you can do whatever you want here
::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);
}
static DWORD WINAPI RunStuff(LPVOID param)
{
int data = reinterpret_cast<int>(param);
//long running operation here
return 0;
}
答案 10 :(得分:0)
您可以使用许多开源跨平台C ++线程库:
其中包括:
Qt的
英特尔
TBB提升线程
您描述它的方式,我认为英特尔TBB或Boost线程都可以。
英特尔TBB示例:
class RunStuff
{
public:
// TBB mandates that you supply () operator
void operator ()()
{
// long running operation here
}
};
// Here's sample code to instantiate it
#include <tbb/tbb_thread.h>
tbb::tbb_thread my_thread(RunStuff);
提升线程示例:
http://www.ddj.com/cpp/211600441
Qt例子:
http://doc.trolltech.com/4.4/threads-waitconditions-waitconditions-cpp.html
(我认为这不符合您的需求,但只是为了完整而包含在这里;您必须继承QThread,实现void run(),并调用QThread :: start()):
如果您只在Windows上编程并且不关心跨平台,也许您可以直接使用Windows线程:
http://www.codersource.net/win32_multithreading.html