【发布时间】:2011-07-04 16:54:00
【问题描述】:
我目前正在为我正在做的一门课程用 C 语言编写一个简单的网络服务器。一个要求是我们实现一个线程池来处理使用 pthread 的连接。
我知道我将如何大致执行此操作(在主线程中调用 accept 并将文件描述符传递给 freee 线程),但是我的朋友建议了一种替代方法,而不是我想到的方法:创建我的所有线程在前面,让他们都在接受电话时永远循环。想法是接受将阻塞所有空闲线程,并且当连接进入时,仅将文件描述符提供给一个。然后,当给定线程完成连接时,它会循环回来并阻塞再次接受的调用。本质上使用对 accept() 的调用作为信号量。他认为这将大大简化实现,因为您不需要跟踪哪些线程很忙,哪些线程已准备好进行连接。理论上延迟也会更低,因为线程可以立即开始执行。
我的问题是,这安全吗?我打算实施它并尝试一下,但我还没有准备好,我很想知道答案。我在谷歌和stackoverflow上搜索过,但找不到任何人这样做。接受线程安全吗?我认为这种方法会产生更多开销,因为您一直在运行所有线程,这两种方法只是简单的内存/延迟权衡吗?
编辑:我不确定这是否应该是社区维基,如果应该是道歉,我找不到按钮:P
【问题讨论】:
-
这里要小心一点,“线程安全”的 POSIX 定义意味着您可以从不同的线程同时调用该函数。这并不意味着您一定可以同时调用函数改变相同的数据,结果可预测,甚至可以定义行为。
strcpy是线程安全的,但它不会占用任何类型的锁。在 POSIX 中,“非线程安全”意味着 非常 不安全。根据 POSIX 定义,accept()是线程安全的(即不在此列表中:pubs.opengroup.org/onlinepubs/009695399/functions/…),但您需要的不止这些。 -
@Steve:虽然这对于您传递指针的接口是一个有效的警告,但它不适用于文件描述符/套接字。 OP 的使用非常安全。
-
@R..:我认为它可能是安全的,但 POSIX 在哪里解释/定义它?除了“线程安全”之外,它还有一个特定的术语吗?
-
@EJP:你会想,不是吗?但是例如 opengroup 没有在它定义“线程安全”的地方定义“原子”:pubs.opengroup.org/onlinepubs/9699919799/basedefs/…。我无权访问 IEEE 发布的 POSIX 标准以进行正确检查。
-
@Rick:系统调用应该始终是线程安全的。内核必须具有该级别的安全性才能正确运行。这是因为所有进程共享同一个内核,并且在内核内部时,来自两个独立进程的系统调用的执行看起来就像内核中的两个执行线程。 POSIX 不定义系统调用,只定义 API 的行为。如果 API 在特定实现中被实现为系统调用,则需要使其成为线程安全的。
标签: c pthreads threadpool sockets