C语言中的多线程编程,跨平台

16

我正在处理一个现有的C语言项目,目前运行在单个线程上,我们希望能在多个平台上运行并使用多个线程。希望有一个库能够实现这一点,因为Win32 API就像反复戳自己的眼睛一样。我知道Boost.Thread适用于C++,但是这必须是C(并且可以在MinGW和gcc上编译)。遗憾的是,Cygwin不是一个选项。


1
如果你认为CreateThread就像不断戳自己的眼睛,那么你不应该尝试这样做。 - asveikau
8个回答

14

试试OpenMP API,它是多平台的并且可以使用GCC编译。

维基百科的简要说明:

OpenMP(Open Multi-Processing)是一个应用程序编程接口(API),支持在C、C++和Fortran中进行多平台共享内存多处理编程,在大多数平台、处理器架构和操作系统上,包括Solaris、AIX、HP-UX、Linux、macOS和Windows。它由一组编译器指令、库例程和环境变量组成,影响运行时行为。


6
在使用OpenMP一年多后,我可以向读到这个问题的每个人保证,它绝对值得花费时间。 - Dhaivat Pandya
1
链接失效,尝试编辑,但网站提示我至少要编辑6个字符... - RP.

9
我会使用POSIX线程API——pthread。这篇文章提供了在Windows上实现它的一些提示,并提供了一个仅包含头文件的下载(BSD许可证):

http://locklessinc.com/articles/pthreads_on_windows/

编辑:我过去使用过sourceforge的pthreads-win32项目进行多平台线程处理,效果非常好。现在事情已经有所变化,上面的链接似乎更加更新,不过我还没有尝试过。当然,这个答案假定你的非Windows目标平台上有pthread可用(对于Mac/Linux来说应该是有的,甚至可能嵌入式系统也有)。

4

Windows的线程功能与Linux有很大不同,因此如果应用程序性能可能成为问题,您应该考虑两种不同的实现方式。另一方面,仅仅实现多线程可能会使您的应用程序比以前更慢。假设性能是一个问题,并且多线程是最佳选择。

对于Windows线程,我特别考虑了I/O完成端口(IOCP),它允许实现I/O事件驱动线程,从而最有效地利用硬件。

许多“经典”应用程序都是沿着一个线程/一个套接字(/一个用户或类似)的概念构建的,其中同时会话的数量将受到调度程序处理大量线程(>1000)的能力的限制。 IOCP概念允许将线程数限制为系统中的核心数,这意味着调度程序将几乎没有任何操作。线程仅在IOCP释放它们后才执行,此时发生了I/O事件。线程服务IOC,(通常)启动新的I/O并返回到IOCP等待下一个完成。在释放线程之前,IOCP还将提供完成的上下文,以便线程将“知道”IOC属于哪个处理上下文。

IOCP概念完全摆脱了轮询,这是一种很大的资源浪费,尽管“等待多个对象”轮询略有改进。我上次查看Linux时,它没有任何类似于IOCP的东西,因此与具有IOCP的Windows应用程序相比,Linux多线程应用程序将构建得完全不同。

在非常高效的IOCP应用程序中,存在这样的风险,即向涉及IO资源的IO(或输出)排队的数量太多,以至于系统无法存储它们的非分页内存。相反,在非常低效的IOCP应用程序中,存在这样的风险,即等待服务的输入太多,以至于在尝试临时缓冲它们时耗尽了非分页内存。


3

这里最好/最简单的答案肯定是使用 pthreads。这是 Unix/POSIX 系统的本地线程架构,在 Windows 上也几乎同样有效。无需再寻找其他。


不使用win32 API,它能在Windows上编译吗? - Dhaivat Pandya
5
在Windows上,如果不使用Win32 API,就无法进行线程处理,就像在Unix上没有内核hackery或使用pthreads API也无法进行线程处理一样。您的应用程序需要担心Win32 API吗? 不需要,这就是为什么有一个与MinGW一起提供的pthread-win32库。请注意,尽管该库可与MSVC一起使用,但它不是您使用Visual Studio获得的Windows SDK的一部分。但我默认您将使用MinGW。 - rubenvb

3
如果有人需要一种轻便且便携的C语言线程解决方案,可以看看 plibsys库。它为您提供线程管理和同步,以及其他有用的功能,如可移植的套接字实现。所有主要操作系统(Windows、Linux、OS X)都受支持,还支持各种其他较不流行的操作系统(例如AIX、HP-UX、Solaris、QNX、IRIX等)。在每个平台上,只使用本地调用来最小化开销。该库完全覆盖了单元测试,并定期运行。

2

1
我再也不会为C使用对象包装器了。我已经放弃了glib,抱歉。 - Dhaivat Pandya
1
它被广泛应用。你的问题是什么? - Manuel Salvadores

2

考虑到你使用C语言受到限制,我有两个建议:

1)我曾经见过一个类似于你的项目,需要在Windows和Linux上以线程方式运行。它的编写方式是,在Linux上使用pthread,在Windows上使用win32线程(相同的代码库)。这是通过条件#ifdef语句实现的,无论何时需要创建线程,都要使用该语句。

#ifdef WIN32

//use win32 threads

#else

//use pthreads

#endif

2) 第二个建议可能是使用OpenMP。您考虑过OpenMP吗?

如果我漏掉了什么或者您需要更多细节,请告诉我。我很乐意帮助。

最好的祝福, Krishna


1
如果我想要那样做,那我就不会请求使用库了,因为我说过我想要的东西不使用win32 API。 - Dhaivat Pandya

0

根据我的经验,Windows 平台下的 C 多线程编程与 Win32 API 密切相关。其他语言如 C# 和 JAVA,虽然由框架支持,但也绑定了这些核心库以提供线程类。

然而,我在 SourceForge 上找到了一个名为 openthreads 的 API 平台,可能会对您有所帮助:

http://openthreads.sourceforge.net/

该API是根据Java和POSIX线程标准建模的。

我自己还没有尝试过,因为目前我的C/C++项目不需要支持多个平台。


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