C 最好锁定一个共享资源,或者有一个线程来完成请求?

C 最好锁定一个共享资源,或者有一个线程来完成请求?,c,locking,pthreads,mutex,task-queue,C,Locking,Pthreads,Mutex,Task Queue,我有一个共享内存池,许多不同的线程可以从中请求分配。在每个线程中都会大量请求分配,但是线程的数量可能很小,通常只有一个线程在运行。我不确定以下哪种处理方法更好 最终,我可能需要实现这两个目标,看看哪一个能产生更有利的结果。。。我还担心,即使考虑到#2,在这一点上也可能是过早的优化,因为我实际上还没有编写使用此共享资源的代码。但是这个问题太有趣了,它继续让我从其他工作中分心 1) 创建一个互斥锁,并让线程在获得分配之前尝试锁定它,然后解锁它 2) 让每个线程注册一个请求槽,当它需要分配时,它将请求

我有一个共享内存池,许多不同的线程可以从中请求分配。在每个线程中都会大量请求分配,但是线程的数量可能很小,通常只有一个线程在运行。我不确定以下哪种处理方法更好

最终,我可能需要实现这两个目标,看看哪一个能产生更有利的结果。。。我还担心,即使考虑到#2,在这一点上也可能是过早的优化,因为我实际上还没有编写使用此共享资源的代码。但是这个问题太有趣了,它继续让我从其他工作中分心

1) 创建一个互斥锁,并让线程在获得分配之前尝试锁定它,然后解锁它

2) 让每个线程注册一个请求槽,当它需要分配时,它将请求放入槽中,然后阻塞(而(result==NULL){usleep()})等待请求槽产生结果。单个线程连续迭代请求槽,进行分配,并将它们分配给请求槽中的结果

数字1是一个简单的解决方案,但如果时机合适,单个线程可能会占用锁。第二种方法更复杂,但在从资源中提取时确保线程之间的公平性。但是,它仍然会阻塞请求线程,如果有许多线程,迭代可能会在找到要完成的请求之前,在不进行任何实际分配的情况下燃烧周期


注意:在Linux上使用pthreads的C解决方案2是假的。这是一个丑陋的黑客,它不能确保内存同步

我会说使用解决方案1,但我对您首先提到的“内存池”有点怀疑。您是在尝试分配内存,还是在管理其他资源(例如,某些特殊类型内存中的插槽、内存映射文件、视频内存中的纹理等)

如果您只是在分配内存,那么您担心过早优化是完全正确的。整个问题都是过早的优化,系统
malloc
的性能将与内存池的性能相同或更好。(或者,如果您的代码将运行在少数几个具有病态损坏的
malloc
的系统中的一个,就像某些视频游戏机一样,只需在已知损坏的系统上更换代码即可。)


如果您确实有需要管理的特殊资源,请从解决方案1开始,看看它是如何工作的。如果您有问题,您可能会发现您可以使用一个条件变量来改进它,其中资源管理器会通知您何时可以分配插槽,但我真的怀疑这是否必要。

解决方案2是假的。这是一个丑陋的黑客,它不能确保内存同步

我会说使用解决方案1,但我对您首先提到的“内存池”有点怀疑。您是在尝试分配内存,还是在管理其他资源(例如,某些特殊类型内存中的插槽、内存映射文件、视频内存中的纹理等)

如果您只是在分配内存,那么您担心过早优化是完全正确的。整个问题都是过早的优化,系统
malloc
的性能将与内存池的性能相同或更好。(或者,如果您的代码将运行在少数几个具有病态损坏的
malloc
的系统中的一个,就像某些视频游戏机一样,只需在已知损坏的系统上更换代码即可。)


如果您确实有需要管理的特殊资源,请从解决方案1开始,看看它是如何工作的。如果您有问题,您可能会发现您可以使用一个条件变量来改进它,其中资源管理器会通知您何时可以分配插槽,但我真的怀疑这是否必要。

在您的解决方案2中,如何确保对结果的原子访问?而
usleep()
(附带一个参数)的手册页说它暂停了调用过程;它只是由一个不知道或不知道线程存在的人写的。
usleep
的正确文档如下:@R。。旧的Linux手册页面(如Linux.die)在这种情况下是错误的。顺便说一下,请注意,
usleep
在最新版本中已从POSIX中删除,并且在以前的版本中已标记为过时
nanosleep
应该用于现代应用。在您的解决方案#2中,如何确保原子访问结果?而
usleep()
(附带一个参数)的手册页说它暂停了调用过程;它只是由一个不知道或不知道线程存在的人写的。
usleep
的正确文档如下:@R。。旧的Linux手册页面(如Linux.die)在这种情况下是错误的。顺便说一下,请注意,
usleep
在最新版本中已从POSIX中删除,并且在以前的版本中已标记为过时
nanosleep
应用于现代应用。