谁能举一个简单的例子,在c++中启动两个(面向对象的)线程。
我正在寻找实际的c++线程对象,我可以扩展运行方法(或类似的东西),而不是调用C风格的线程库。
我省略了任何特定于操作系统的请求,希望回复的人会回复使用的跨平台库。我现在把它说得很清楚了。
谁能举一个简单的例子,在c++中启动两个(面向对象的)线程。
我正在寻找实际的c++线程对象,我可以扩展运行方法(或类似的东西),而不是调用C风格的线程库。
我省略了任何特定于操作系统的请求,希望回复的人会回复使用的跨平台库。我现在把它说得很清楚了。
当前回答
这在很大程度上取决于您决定使用的库。例如,如果你使用wxWidgets库,线程的创建将是这样的:
class RThread : public wxThread {
public:
RThread()
: wxThread(wxTHREAD_JOINABLE){
}
private:
RThread(const RThread ©);
public:
void *Entry(void){
//Do...
return 0;
}
};
wxThread *CreateThread() {
//Create thread
wxThread *_hThread = new RThread();
//Start thread
_hThread->Create();
_hThread->Run();
return _hThread;
}
如果主线程调用CreateThread方法,您将创建一个新线程,该线程将开始执行“Entry”方法中的代码。在大多数情况下,您必须保持对线程的引用才能加入或停止它。
更多信息在wxThread文档中。
其他回答
好吧,从技术上讲,任何这样的对象都将在C风格的线程库上构建,因为c++只是在c++ 0x中指定了一个常规std::thread模型,这个模型刚刚被确定下来,还没有实现。
这个问题有点系统性。从技术上讲,现有的c++内存模型还不够严格,无法为所有“happens before”情况提供定义良好的语义。Hans Boehm不久前写了一篇关于这个主题的论文,并在关于这个主题的c++ 0x标准的制定中发挥了重要作用。
线程不能作为库实现
也就是说,有几个跨平台的线程c++库在实践中工作得很好。Intel线程构建块包含一个tbb::thread对象,它非常接近c++ 0x标准,Boost有一个Boost::thread库,它也有同样的功能。
oneAPI线程构建块 19章。线程(Boost文档)
使用boost::thread,你会得到类似这样的东西:
#include <boost/thread.hpp>
void task1() {
// do stuff
}
void task2() {
// do stuff
}
int main (int argc, char ** argv) {
using namespace boost;
thread thread_1 = thread(task1);
thread thread_2 = thread(task2);
// do other stuff
thread_2.join();
thread_1.join();
return 0;
}
还有一个用于POSIX操作系统的POSIX库。
检查兼容性:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
void *task(void *argument){
char* msg;
msg = (char*)argument;
std::cout << msg << std::endl;
}
int main(){
pthread_t thread1, thread2;
int i1, i2;
i1 = pthread_create(&thread1, NULL, task, (void*) "thread 1");
i2 = pthread_create(&thread2, NULL, task, (void*) "thread 2");
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
使用-lpthread编译。
POSIX线程
#include <thread>
#include <iostream>
#include <vector>
using namespace std;
void doSomething(int id) {
cout << id << "\n";
}
/**
* Spawns n threads
*/
void spawnThreads(int n)
{
std::vector<thread> threads(n);
// spawn n threads:
for (int i = 0; i < n; i++) {
threads[i] = thread(doSomething, i + 1);
}
for (auto& th : threads) {
th.join();
}
}
int main()
{
spawnThreads(10);
}
这在很大程度上取决于您决定使用的库。例如,如果你使用wxWidgets库,线程的创建将是这样的:
class RThread : public wxThread {
public:
RThread()
: wxThread(wxTHREAD_JOINABLE){
}
private:
RThread(const RThread ©);
public:
void *Entry(void){
//Do...
return 0;
}
};
wxThread *CreateThread() {
//Create thread
wxThread *_hThread = new RThread();
//Start thread
_hThread->Create();
_hThread->Run();
return _hThread;
}
如果主线程调用CreateThread方法,您将创建一个新线程,该线程将开始执行“Entry”方法中的代码。在大多数情况下,您必须保持对线程的引用才能加入或停止它。
更多信息在wxThread文档中。
除非想在全局名称空间中使用单独的函数,否则可以使用lambda函数来创建线程。
使用lambda创建线程的主要优点之一是不需要将局部参数作为参数列表传递。我们可以使用相同的捕获列表,lambda的闭包属性将负责生命周期。
下面是示例代码:
int main() {
int localVariable = 100;
thread th { [=]() {
cout << "The value of local variable => " << localVariable << endl;
}};
th.join();
return 0;
}
到目前为止,我发现c++ lambdas是创建线程的最佳方式,特别是对于更简单的线程函数。