用C/C++创建多线程应用程序的最简单方法是什么?

6

如何使用C/C++最简单地创建多线程应用程序?


8
最简单的编写并发程序的方法是不显式地使用线程。您想做什么? - Amok
2
C++的下一个版本,亲切地被称为C++0x,正在得到线程处理功能:http://en.wikipedia.org/wiki/C%2B%2B0x#Threading_facilities - luke
1
卢克 - 这仍然不会变得容易! - Martin Beckett
你是指C还是C++?它们是不同的编程语言。Boost.Thread在C中无法工作,而pthreads对于大多数C++程序员来说可能太低级了。 - Tom
15个回答

14

在任何语言中创建多线程应用程序都没有简单的方法。


8
这并不是真的。选择适合任务的编程语言可以使多线程编程变得容易。 - Amok
3
我问了关于最简单的方法。 - SomeUser
6
使用简单的语言实现多线程编程可能看起来很容易,但这是最难正确解决的编程问题之一。如果你认为自己足够聪明可以实现正确的多线程编程,那么你很可能是错的。 - Esteban Küber
4
Amuck: 多线程编程从来都不容易。无论有多少支持,解决死锁、自旋等多线程编程的问题都不容易。 - jmucchiello
2
即使编写多线程应用程序的每种方法都很困难,按定义至少其中一种方法必须是最容易的。 :p - Philip Davis
显示剩余9条评论

14

很遗憾,没有简单的方法。几个选项:在Linux上使用pthread,在Windows上使用win32 api线程或boost::thread库。


8

如果你的程序可以适应这个模型,那么这绝对是最简单的方法。事实上,我正在编写一个短小的测试程序,使用OpenMP就是为了这个原因。 - Max Lybbert

7

5

4
这是我认为不太有帮助的事情,尤其是与使用boost库的建议相比。Posix在Win32环境下不易移植,并且API非常基础。 - Jherico
它显然不会让多线程编程变得容易,但至少它有很好的文档记录。 - Carl Norum
pthread在Windows上得到支持:http://sourceware.org/pthreads-win32/ 所有线程API都是原始的...如果您想要更高级别的话,可以使用线程池、actors或其他抽象层来处理线程。 - Greg Rogers
pthreads 在 Windows 上运行良好。Windows API 不就是 pthreads 的一层封装吗? - Martin York
1
@Greg:虽然并非所有的线程API都是“石器时代”的原始方式。Boost成功实现了一个保持类型安全且在C++应用程序中表现良好的线程API。相比之下,pthread在使用上并没有提供便利,也无法防止程序员的错误。 - jalf
pthread 可能不太算是“最简单”的线程库,因为还有其他一些非常容易使用的线程库。但我认为这并不是一个坏答案,因为在 POSIX 平台上 pthreads 是“源泉之力”。 - Tom

5

没有简单的答案。这取决于您希望从多线程中获得什么,平台/编译器以及要使用的线程模型。每个线程API都有其缺陷。

而且仅仅因为迄今为止没有人提到它,OpenMP是另一种选择,它在许多现代主流编译器中得到支持,旨在简化并发使用。 http://openmp.org/wp/


3

我已经有一段时间没有使用C++了,也没有接触过Boost线程支持,但是我发现将操作系统提供的信号量服务封装在简单的类中非常有用,通常这些服务由POSIX或Win32提供,这样可以在类中获取锁,并在析构函数中释放它们,使得使用变得相当简单。

void operateOnSharedResource(SharableResource & foo) {
    MutexLock lock(foo.getMutex());
    // do stuff to foo
    // implicit call to MutexLock dtor performs release 
}

最终,有很多简单的技巧可以使线程编程更加轻松,如果Boost现在没有类似的东西(编辑:它有,并且在锁类型中有文档),我会感到惊讶。

尽管如此,编写多线程代码的主要问题不会被任何第三方库解决,这就是理解您的代码在哪里可以有用地并行化以及在哪里会涉及共享资源并且必须加以考虑的问题。以下是我在编写多线程代码时使用的一些经验法则:

  • 尽量减少共享资源的数量
  • 尝试将共享资源封装在类包装器中,以使所有操作都是原子的。
  • 使工作线程尽可能简单

适当的封装确实可以为编写更安全的多线程代码带来奇迹,因为您能看到的东西越少,竞争条件就越少。


2

C++0x规范包括线程功能(这是我最喜欢的新特性之一)。很快,无论您编译哪个操作系统,都不会有问题!看看创建新线程并返回到创建者线程有多简单:

#include <thread>
#include <iostream>

class SayHello
{
public:
    void operator()() const
    {
        std::cout<<"hello"<<std::endl;
    }
};

int main()
{
    std::thread t((SayHello()));
    t.join();
}

Visual Studio 2010正在实现C++0x的部分功能,但我们仍在等待线程工具。


只要你愿意忍受C++,你就可以做到。如果你想这样做,现在就可以用Java实现。 - Carl Norum
兄弟...这个问题规定了C/C++。 - James Jones
1
@James,除非最近有所改变,否则我认为std::thread不会成为现有实现(如POSIX线程)的完全替代品。特别是它缺少线程优先级等功能。有关详细信息,请参见此SO答案:https://dev59.com/QUjSa4cB1Zd3GeqPJOGu#1274301...无论如何,毫无疑问,std::thread将成为标准中非常受欢迎的补充。 - Void

2

我不确定哪个是最简单的,但在我看来,最用户友好的线程库是包含在Poco C++项目中的库。预览请查看Thread.h头文件。


2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接