2010-06-26 82 views
9

我想开始在C++中学习多线程。我也在Java中学习它。在Java中,如果我编写使用多线程的程序,它可以在任何地方工作。但是在C++中,多线程不依赖于平台特定的API?如果是这样,这似乎妨碍了便携性。C++多线程......从哪里开始?

如何在不导致可移植性问题的情况下使用C++进行多线程? boost的thread库是一个很好的解决方案吗?

作为旁注 - 如何甚至可以将多线程实现为库?这不是编译器必须做的事吗?

+1

作为一个谨慎的话,你将不得不在C++中思考更多关于线程安全性的内容。我们不能只为类方法撒上同步关键字,以使它们安全。你通常会使用像互斥锁或其他形式的关键部分,原子操作等工具。但是,如果你做得对,你将能够编写非常高效的多线程代码。你甚至可以使用每线程内存池编写你自己的内存分配器,但它比Java更低一级并且难以正确编写。 – stinky472 2010-06-27 02:28:59

+0

(+1)@ stinky472:这就是为什么我想学习C++和Java中的多线程。我觉得Java通常适用于许多主题的高层次介绍,但只要坚持使用Java,可能会让程序员有点过分,并且不会将它们暴露给一些非常重要的概念。因此,当我在Java中学习多线程时,我正在用C++同时学习它,以确保我正在学习所有我应该学习的东西。 – Cam 2010-06-27 03:32:17

回答

13

如果您还没有支持C++0x尚(可与Visual Studio C++ 2010为例),使用升压线程的编译器。 (除非你使用已经支持线程的框架,否则你不会问这个问题 - )。这些提升线程成为全新C++中的标准。在那之前,C++本身并不知道。

TBB Threading Building Blocks如果您想了解并行编程中的其他方面,也可能对您感兴趣。

关于Qt:如果你只想要线程支持,那么它是完整的矫枉过正。从编译到结果的往返时间都非常慢。这是非常精心设计的思想。但不是官方的标准,比如来自boost的C++ 0x线程。所以我不会把它作为第一选择。

+0

谢谢。所有的答案都非常有用,但是这是最有信息的imo。 – Cam 2010-06-26 20:37:07

3

在C++中,yes线程是平台特定的。然而,许多线程库在各种平台上封装了线程的细微差别,提供了一个统一的API来编写线程应用程序,因此您不必担心平台特定的细节。

Boost线程库是一个很好的解决方案。

我也推荐检出ACE

1

为了提供与Boost不同的建议,我使用Pthreads(或Windows上的Pthreads-Win32)。这是一个非常亲自动手的准系统库,但可以为您提供您所需要的一切,而无需其他。与Boost相比,它非常轻巧,你可以很容易地找到它的C++包装,为你提供更高层次的抽象。

+0

来自boost的线程库是一个模板“仅头文件”库。它不会产生任何大的开销。好的,所需的一堆文件可能很大,但最终的结果是只有模板实例的几个字节。 – jdehaan 2010-06-26 18:12:02

+0

@jdehaan:你可以扩展“模板”标题“库”的含义吗? – Cam 2010-06-26 18:30:53

+3

我必须承认,我也很惊讶“头只”。这个:'libboost_thread-vc100-mt-gd-1_43.lib'看起来不像头。 – 2010-06-26 18:59:48

4

让我们落后开始:

怎么可能实现在库中的线程?

它不是,至少不是(纯粹的)C++。这需要语言支持(编译器只是一个实现)。

目前,两件事情被使用:(在pthread库等)的某些部分

  • 汇编代码
  • 他人特定的编译器指令(依赖于编译器和平台)

两者都很脆,需要大量的便携性工作。基本上,这意味着很多#ifdef部分代码在测试编译器和目标体系结构,测试是否支持某些指令等...

这就是为什么认为有必要在C++ 0x中添加线程支持。

我该如何做多线程?

即使在您选择库之前,您应该选择一种方法。有编程多线程应用2种方式(你可以将它们组合起来):

  • 通过共享通信:这意味着使用互斥量,原子操作,等等......你可以在Linux平台上使用pthread,但我将推荐Boost.Thread(其中包括)的便携性。
  • 通过沟通分享:更新,适应分布式计算,这源于功能语言。这意味着将消息从一个线程传递到另一个线程,而不共享任何资源。您可以使用FastFlow或英特尔的Thread Building Blocks又名TBB

你可以想象将两者合并,但最好不要这样做。就我个人而言,我发现FastFlow的描述非常棒:它鼓励无锁编程。另外,第二种方法的主要优点是它更适合于多进程编程和扩展到分布式环境。

首先,我会建议重点关注其中之一并用它构建一些应用程序。当你感觉舒服时,你可以尝试另一种,但准备好重新开始,他们是不同的。

+0

它不支持线程的编译器,它取决于操作系统。例如,在纯C++中执行此操作的方式是包含pthreads头文件,使用它的函数并链接到它的lib文件。编译器对pthreads本身一无所知。 – Gianni 2010-06-26 19:16:48

+0

那么,我会说使用基于程序集的库不使用纯C++;)我将更正编译器的东西,但我的意思是语言。 – 2010-06-26 19:24:36

+0

@Matthieu我的意思是,应用程序实际上只是向操作系统请求一个线程,然后向操作系统创建并初始化线程。 ASM或内置的编译器功能(仅意味着更多的ASM)仅用于原子。互斥体,信号量,线程本身都取决于操作系统。 – Gianni 2010-06-26 19:52:45

1

您可能还会考虑openmp http://openmp.org。许多编译器都支持它,包括MS,GCC/G ++和Intel。尽管你没有得到线程的显式控制,但是它对并行性的更高级的抽象有时更高效(在编码时和运行时),并且代码更容易理解。如果你正在做GUI工作,它不会帮到你很多,但是对于可扩展计算来说,这是值得一看的。

1

Boost线程库可能是最适合C++的地方。为您提供线程构造,以及编写真正可用的多线程应用程序所需的所有互斥锁和控件对象。

0

如果您为了提高您对不同编程模型和语言技能的了解而做出这些贡献,那么Boost库将是一个很好的选择。不过,我会认真考虑使用多线程C++构建任何生产应用程序。

为了在不增加共享内存多线程相当复杂的情况下获得正确性,C++有时足够具有挑战性。即使是最经验丰富的程序员也会同意多线程程序非常难以推理和正确。多线程时,即使最简单的程序也很快就难以测试和调试。例如C++或Java或C#(带有它们的可变变量,共享内存和锁定/信令原语)等命令式语言通常是尝试构建多线程应用程序的最不可能的方式。通常有完美的单线程实现选项来完成大多数用户空间(而不是内核或嵌入式)应用程序问题,包括在多核机器上。

如果您真的想构建可靠的“多线程”应用程序,我建议您查看像Erlang,Haskell,F#或Clojure等函数式语言。

2
//This program explains how pthread works, here 5 thread are trying to update a global variable simultaneously but with locking synchronization in maintained 
#include<iostream> 
#include<pthread.h> 
using namespace std ; 

#define MAX_NO_THREAD 5 

    int global_sum = 0 ; 
    pthread_mutex_t lock ; //Declared global lock mutex object 

void *print_fun(void *arg) 
{ 
    cout<<"\nThread id : "<<(int)arg; 
    pthread_mutex_lock(&lock) ; //aquiring lock on piece of code 
    for (int j=0; j<100000000; j++) 
    { 
     global_sum++ ; 
    } 
    pthread_mutex_unlock(&lock) ; //reomving lock on peice of code 
    cout<<"\nGlobal Sum : "<<global_sum ; 
} 

int main() 
{ 
    int i = 0 ; 
    pthread_t threads_obj[MAX_NO_THREAD] ; //Initializing object array for thread 
    pthread_mutex_init(&lock, NULL) ; //Initalinzing lock object for thread 
    int st ; 
    for (i=0; i<5; i++) 
    { 
     pthread_create(&threads_obj[i], NULL, *print_fun, (void *)i) ;//Initializing threads calling function print_fun 
     pthread_join(threads_obj[i], 0) ; //Forcing main thread to main until these thread complete 
    } 
    pthread_mutex_destroy(&lock) ; //Destroying lock object 
} 



//compile this program using -lpthread option with g++ 
//g++ thread.cc -lpthread