POSIX线程与Win32线程

我只是将脚趾浸入POSIX池中,并首次尝试了POSIX线程。 到现在为止,我一直感觉到POSIX线程和Win32线程之间存在很大的体系结构差异,但是从我尝试的(虽然很小)来看,我并没有真正看到任何差异。

我仍然很好奇-POSIX线程和Win32线程之间有什么区别(如果有)? 它们从根本上是不同的,还是仅存在细微的差异?

 相关讨论

  • "为什么Windows线程比POSIX线程更好?":software.intel.com/zh-cn/blogs/2006/10/19/请务必阅读注释,以获取有趣的内容(不幸的是,该内容的原始来源似乎没有 可供使用,但注释中有)。
  • @MichaelBurr的标题。 顺便说一下,本文已在reddit上进行了讨论。


在Windows NT家族内核和许多Unix内核中,如何"在幕后"管理和调度线程之间存在巨大差异,但这不是问题。

如果您只是在谈论接口(Win32线程和POSIX线程公开的服务),通过一些工作,您几乎可以将任何POSIX线程功能映射到Win32等效?1:1。 它已经完成了(请参阅pthreads-win32)。

我可能注意到的一个很大的不同是,在Win32下,您使用实际的系统调用来处理线程,而POSIX线程的调用是库(pthreads)的一部分,在许多Unix系统下,它调用Unix的一些非常低级的系统调用。 内核(在Linux下有clone())。

只是为了向您证明,除非深入研究,否则pthreads没什么特别的,您可以下载暴露了与pthreads完全相同的接口的pthreads-win32,并且任何函数都映射在Win32线程API上。 而且有效。

 相关讨论

  • +1嗯,现在我很想知道它们在幕后有什么不同。 :-)如果可以的话,请介意进行详细说明,或者指向我可以阅读的内容?看起来很有趣。
  • @Mehrdad:我在大学里一直在研究Win32和(某些)Unix内核的内部结构(尤其是调度),但我不记得所有不能写在评论上的细节及其内容。只是一个例子,让您一窥。在从I / O退回的Win32线程下(刚刚请求了一些I / O并完成了),它们被提升为一个优先级(+1)-我们更喜欢事先安排I / O线程,因为它们可能会用户交互和更少的CPU浪费-在某些Unix内核下,如果继续受I / O约束,它们可以提升许多层次并保持在最高水平。
  • @Mehrdad:但是那很简单。您可能想了解更多,我可以为您介绍一些不错的(技术)书。给我半天,我会找到我的S.O。书。
  • 我不同意一对一的对应关系。尽管我对多线程API不太满意,但是想到的pthread之一就是信号。 WinAPI无法在一个线程中为特定信号设置处理程序,然后从另一个线程向第一个线程发送信号,迫使其中断当前代码并执行该处理程序。当我不得不将一些在GNU / Linux中原型化的应用程序通过C#移植到Windows时,这是一个大问题-看来,"普通"功能在Windows上不可用,从而破坏了抽象层。
  • @ Hi-Angel:我以为信号处理程序是异步的?您如何在没有警告的情况下随机"中断"线程?您是在谈论QueueUserAPC还是SendMessage?
  • @Mehrdad这是一个带有pthread信号的简单而肮脏的示例。出于演示目的,我什至没有放入第二个线程sleep(),即它不调用任何系统函数,而只是重复相同的代码。 1秒后的第一个线程。睡眠后,将SIGUSR1信号发送给孩子,从而迫使其执行处理程序,该处理程序又退出孩子。该示例适用于大多数现代操作系统。虽然不能在Windows上工作。
  • @ Hi-Angel:那不是很危险吗?如果线程持有锁会怎样? (例如,是否分配了内存?)如果其更改了数据结构该怎么办?它几乎保证不能破坏某些东西吗?
  • @Mehrdad我没看到问题-线程将执行处理程序,然后返回到原来的状态,因此不会有任何东西处于不确定状态。我想虽然可能有些地方不能被打扰,例如当执行在内核中时。而且,当然,像往常一样,总会有一个滥用的地方(例如,可以为分段错误设置处理程序,该处理程序将返回到原来的位置而不是退出),但这取决于程序员吗?
  • @ Hi-Angel:"我没看到问题" ...您知道为什么您甚至不能像在信号处理程序中调用malloc一样平凡的事情吗?并且,考虑到这一点,您能否向我解释为什么您认为信号比仅创建一个新线程并运行它更好?后者更安全,限制更少。
  • @Mehrdad那很有趣。当我回答时,我没有想到当再次突然调用同一个处理程序时,该处理程序出现了问题。但我都不知道malloc问题,即链接。我没有看到那与您的问题之间的关系-如果您需要一个新线程,只需创建一个即可。信号(从用户的角度来看)通常用于处理事情,例如从忙于长时间工作的线程获取有关进度的信息。
  • @ Hi-Angel:我不认为进度报告是信号处理程序的正确用例,它更接近滥用...正确的进度报告不应要求异步中断随机线程。

我正在安装 mingw-w64 on Windows,有两个选项: win32线程和posix线程。 我知道win32线程和pthreads之间的区别,但是我不明白这两个选项之间的区别。 我怀疑如果我选择了posix线程,它将阻止我调用像CreateThread这样的WinAPI函数。

似乎这个选项指定了哪个程序或者库将使用哪个线程 API,但通过什么? 由 GCC,libstdc++或者其他事物?

我发现:什么区别thread_posixs和 thread_win32 gcc Windows 港?

简而言之,对于这个版本的mingw,threads-posix发行版将使用 posix API并允许使用 std:: thread,threads-win32将使用 win32api,并禁用标准的std::thread 部分。

好的,如果我选择win32线程,那么 std::thread 将不可用,但是win32线程仍将被使用。 但是用什么?

gcc运行时( 特殊的异常处理)的部分依赖于正在使用的线程模型。 因此,如果你使用的是使用posix线程构建的运行时版本,但决定在你自己的代码中使用 win32 api创建线程,那么你可能会遇到一些问题。

即使你正在使用运行时的win32线程版本,你可能也不应该直接调用 win32 api 。 引用来自 MinGW常见问题解答:

由于MinGW使用了 Windows 附带的标准Microsoft运行时库,所以你应该小心并使用正确的函数来生成一个新的线程。 CreateThread 函数将不会正确地为运行时库设置堆栈。 你应该使用 _beginthreadex,它是( 几乎几乎) 完全兼容 CreateThread 。

GCC附带了一个编译器运行时库( 宋体),它使用( 其中之一) 提供了一个用于在它的支持的语言中实现多线程相关功能的。 最相关的例子是 C++11 libstdc++ <thread><mutex><future>, gcc时没有一个完整的实现了其内部win32线程模型。 MinGW-w64提供了 winpthreads ( Win32多线程API之上的一个pthreads实现),GCC可以链接它来启用所有的奇妙特性。

我必须强调这里选项不允许你编写任何你想要的代码( 对于你可以在代码中调用的API,它有绝对的影响) 。 它只反映了 (libgcc/libstdc++/...) 库的使用了哪些运行时。 由 @James 引用的警告与gcc线程模型的内部无关,而是与microsoft实现的CRT有关。

总结:

  • posix: 启用 c++11/c11多线程功能。 使depend依赖于 libwinpthreads,这样即使你不直接调用 API,你将分发 winpthreads 。 使用应用程序分发一个DLL没有什么问题。
  • win32: 没有C++11多线程功能。

对任何调用 Win32 api或者 pthreads api的用户代码都不影响。 你可以同时使用两个。

原作者:rubenvb

https://ask.helplib.com/windows/post_675746

--------------------------------------------------------------------------------------------------------------------------

我在Windows上安装mingw-w64,有两个选项:win32线程和posix线程。 我知道什么是win32线程和pthreads之间的区别,但我不明白这两个选项之间的区别是什么。 我怀疑,如果我会选择posix线程,它会阻止我调用像CreateThread WinAPI函数。

看来这个选项指定哪个线程API将被一些程序或库使用,但是通过什么? 通过海湾合作委员会,libstdc ++或其他?

我发现这个: 在windows的gcc端口thread_posixs和thread_win32之间有什么区别?

总之,对于这个版本的mingw,threads-posix版本将使用posix API并允许使用std :: thread,并且threads-win32将使用win32 API,并禁用std :: thread的部分标准。

好的,如果我将选择win32线程,那么std :: thread将不可用,但仍将使用win32线程。 但是用什么?

GCC带有一个编译器运行库(libgcc),它用于(除其他外)提供一个底层操作系统抽象,用于支持多语言相关功能。 最相关的例子是libstdc ++的C ++ 11 <thread> , <mutex><future> ,当使用内部的Win32线程模型构建GCC时,没有完整的实现。 MinGW-w64提供了一个winpthreads(在Win32多线程API之上的一个pthreads实现),然后GCC可以链接到所有的奇特功能。

我必须强调这个选项并不禁止你编写任何你想要的代码(它对你可以在代码中调用的API 没有任何影响)。 它只反映了GCC运行时库(libgcc / libstdc ++ / ...)使用的功能。 @James引用的警告与GCC的内部线程模型无关,而与微软的CRT实现无关。

总结:

  • posix :启用C ++ 11 / C11多线程功能。 使libgcc依赖于libwinpthreads,所以即使不直接调用pthreads API,也会分发winpthreads DLL。 分配一个更多的DLL与您的应用程序没有任何问题。
  • win32 :没有C ++ 11多线程功能。

对任何调用Win32 API或pthreads API的用户代码都没有影响。 你可以一直使用两者。

GCC运行时的一部分(尤其是异常处理)依赖于正在使用的线程模型。 因此,如果您使用的是使用POSIX线程构建的运行时版本,但是决定使用Win32 API在自己的代码中创建线程,则可能在某个时候出现问题。

即使使用运行时的Win32线程版本,也可能不应该直接调用Win32 API。 从MinGW常见问题引用:

由于MinGW使用Windows附带的标准Microsoft C运行时库,所以应该小心并使用正确的函数来生成新的线程。 特别是, CreateThread函数不会为C运行时库正确设置堆栈。 您应该使用_beginthreadex ,而(几乎)与CreateThread完全兼容。

请注意,现在可以在win32线程模式下使用一些C ++ 11 std :: thread。 这些仅供头部使用的适配器为我开箱即用: https : //github.com/meganz/mingw-std-threads

从修订历史看来,最近有一些尝试将其作为mingw64运行时的一部分。

https://code.i-harness.com/zh-CN/q/1071994

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在C语言中,要实现跨平台的线程代码封装,可以使用一些开源的跨平台线程库,如POSIX Threads(pthread)库或Windows Threads库。 首先,可以定义一个封装线程的结构体,包含线程的标识符(ID)和线程的处理函数。此结构体可以定义在一个头文件中,以便在多个源文件中使用。 在封装跨平台线程的函数中,可以使用条件编译以区分不同的操作系统或编译器。例如,可以使用#ifdef和#endif指令将不同平台的代码块区分开来。 在跨平台线程的封装函数中,可以根据操作系统的不同调用不同的线程库函数。例如,在Unix-like系统中,可以调用pthread_create函数创建一个新的线程,并将线程的处理函数和参数传递给它。而在Windows系统中,可以调用CreateThread函数完成相同的任务。 另外,还可以定义一些其他的线程操作函数,如线程的等待、线程的退出等。这些函数可以通过调用不同平台的线程库函数来实现。 为了更好地跨平台,可以将这些封装函数放在一个单独的源文件中,然后在其他源文件中引入头文件,并调用这些函数来创建和操作线程。在编译时,可以根据不同平台的编译器要求链接不同的线程库,以确保代码能够在不同的平台上正常运行。 总的来说,通过使用开源的跨平台线程库,并使用条件编译来区分不同的操作系统或编译器,可以封装C语言的跨平台线程代码。这样可以使线程的创建和操作在不同的平台上都能正常运行,提高了代码的可移植性和跨平台性。 ### 回答2: C语言是一种面向过程的编程语言,不直接支持线程封装。但是可以通过使用操作系统提供的多线程库来实现跨平台的线程功能。 在C语言中,常用的多线程库有POSIX线程库(pthread)和Windows线程库。这些库提供了一组函数和结构体,可以实现线程的创建、销毁、同步和通信等操作。 为了实现跨平台的线程功能,可以根据不同平台选择相应的线程库,并将线程相关的代码封装为独立的模块或者库文件,以实现可移植性。 封装线程代码的主要步骤如下: 1. 定义线程相关的数据结构和函数接口:包括线程ID、线程属性、线程函数等。可以使用结构体定义数据结构,使用函数接口定义线程的创建、销毁、同步和通信等操作。 2. 根据目标平台选择合适的线程库:根据需要跨平台运行,可以选择POSIX线程库或者Windows线程库。 3. 实现线程相关的函数接口:根据所选择的线程库,使用相应的函数接口实现线程的创建、销毁、同步和通信等操作。这些函数接口可以封装在独立的源文件中,并提供给调用者使用。 4. 编译和链接线程相关的代码:将封装了线程功能的源文件编译成目标文件,然后与其他代码一起链接生成可执行程序或者库文件。 通过以上步骤,可以将C语言的线程代码进行封装,实现跨平台的线程功能。这样,在不同的操作系统和编译器环境下,都可以通过调用相同的线程接口来编写跨平台的多线程应用程序。 ### 回答3: C语言是一种跨平台编程语言,提供了基本的线程操作函数,如创建线程、销毁线程线程等待等。然而,由于不同操作系统的线程实现方式和函数接口可能有所不同,因此在编写跨平台的线程代码时需要进行一定的封装。 首先,在不同操作系统下创建线程的方式是不同的。在Windows系统下,可以使用Win32 API中的CreateThread函数创建线程;而在Linux系统下,可以使用pthread库提供的pthread_create函数创建线程。为了实现跨平台兼容,我们可以创建一个封装函数,接受参数包括线程函数、传递给线程函数的参数以及线程标识符。在函数内部通过编译条件判断来选择合适的创建线程的函数。 其次,在线程的入口函数上也需要进行封装。在不同操作系统下,线程的入口函数格式可能有所不同。在Windows系统下,线程入口函数需要返回DWORD类型,而在Linux系统下,线程入口函数需要返回void*类型。为了实现跨平台兼容,我们可以定义一个函数指针类型,根据操作系统的不同选择合适的函数指针类型,并使用该函数指针类型来声明线程的入口函数。 最后,在线程的同步和互斥操作上也需要进行封装。在不同操作系统下,线程同步和互斥的机制也可能有所不同。在Windows系统下,可以使用Win32 API提供的信号量、互斥量等来实现线程同步和互斥;而在Linux系统下,可以使用pthread库提供的信号量、互斥量等来实现。为了实现跨平台兼容,我们可以定义一组封装函数,在不同操作系统下选择合适的函数来实现线程同步和互斥。 总之,通过对C语言跨平台线程的代码进行封装,我们可以在不同操作系统下实现相同功能的线程代码。这种封装不仅可以提高代码的可移植性,还可以简化代码的编写和维护工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值