在线程同步中使用互斥锁时的速度损失 [已关闭]

The Speed Loss When i use mutex in Thread Synchronization [closed]

提问人:zzz 提问时间:11/2/2023 更新时间:11/3/2023 访问量:65

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

21天前关闭。

截至 21 天前,社区正在审查是否重新讨论此问题。

我使用互斥锁排除来通知四个子线程来解码代码流,但我发现与仅使用单线程相比,它花费了更多的时间。(这四个线程分别解码此代码流的四分之一,但单个线程解码整个代码流。

首先我定义了八个互斥锁(四个用于通知解码开始,另外四个用于通知解码结束)

    pthread_mutex_lock(&(mymultidecoder->mutex1));
    pthread_mutex_lock(&(mymultidecoder->mutex2));
    pthread_mutex_lock(&(mymultidecoder->mutex3));
    pthread_mutex_lock(&(mymultidecoder->mutex4));
    pthread_mutex_lock(&(mymultidecoder->overflag1));
    pthread_mutex_lock(&(mymultidecoder->overflag2));
    pthread_mutex_lock(&(mymultidecoder->overflag3));
    pthread_mutex_lock(&(mymultidecoder->overflag4));

其次,在释放线程时先取互斥锁,当我想解码我的码流时,我释放我的静音,就像遵循代码一样:

    (do some prepare)
    pthread_mutex_unlock(&(mymultidecoder->mutex1));
    pthread_mutex_unlock(&(mymultidecoder->mutex2));
    pthread_mutex_unlock(&(mymultidecoder->mutex3));
    pthread_mutex_unlock(&(mymultidecoder->mutex4));

子线程的进程代码如下,(示例线程 1)

 pthread_mutex_lock(&(mymultidecoder->mutex1));
 (decode)
 pthread_mutex_unlock(&(mymultidecoder->overflag1)); // this send signal for decode over

我等待互斥锁确保所有线程都已解码,如下所示:

pthread_mutex_lock(&(mymultidecoder->overflag1));
pthread_mutex_lock(&(mymultidecoder->overflag2));
pthread_mutex_lock(&(mymultidecoder->overflag3));
pthread_mutex_lock(&(mymultidecoder->overflag4));
C++ Linux 多线程

评论

2赞 Caleth 11/2/2023
你的问题是什么?
0赞 Drew Dormann 11/2/2023
立即停下来阅读导览如何提问。这对于在这里提出适当的、切合主题的问题至关重要。猜测如何使用这个网站几乎总是会导致你的问题被关闭和删除。
1赞 Pepijn Kramer 11/3/2023
如果您使用的是C++请使用 std::thread、std::mutex 和 std::scoped_lock。重写代码,显示问题(包括错误)的最小可重现示例,然后再次提出问题。
1赞 Solomon Slow 11/3/2023
看起来好像您正在尝试使所有四个工作线程尽可能接近同一时间启动。为什么?如果第一个工人的开始和最后一个工人的开始之间经过了更多的时间,会发生什么坏事?
0赞 Solomon Slow 11/3/2023
仅供参考:您不能从与锁定互斥锁不同的线程中解锁互斥锁。为此使用binary_semaphore。互斥锁和binary_semaphore非常相似,但“互斥”告诉其他阅读你的代码*的程序员,当他们使用共享变量时,你试图防止线程相互干扰,而“信号量”告诉其他程序员你正在尝试将信号从一个线程发送到另一个线程。[*例如,您寻求帮助以了解某些问题的其他程序员。

答:

6赞 John Bollinger 11/3/2023 #1

我使用互斥锁排除来通知四个子线程来解码代码流,但我发现与仅使用单线程相比,它花费了更多的时间。

是的,某些过程的并行版本可能比相应的串行版本性能更差。操作互斥锁等活动的开销是常见原因之一。

因此,有效并行化的关键之一是确保多个线程并发完成的工作量大于串行完成的工作量。在您的例子中,实际的解码工作是并发的,但所有的准备工作以及所有的互斥锁设置和操作都是串行的(尽管后者是在多个线程中执行的)。

但在您的特殊情况下,......

首先我定义了八个互斥锁(四个用于通知解码开始,另外四个用于通知解码结束)

...听起来很可怕。八个互斥锁?荒谬。互斥锁不太适合信令。一般来说,我可能会推荐一个互斥锁和一个条件变量,使用得当。或者也许是一些信号量。与互斥锁不同,信号量可以通过与锁定信号量(递减为 0)不同的线程解锁(递增)。

但在您的特殊情况下,我不明白为什么您根本不需要任何互斥锁。在启动线程之前,线程不会执行任何工作,因此请先进行所有准备工作。你可以通过ing ing知道每个什么时候完成,无论如何你都应该这样做。如果没有数据竞赛,那么这就是您所需要的。如果存在数据竞争,那么您在问题中描述的内容不会比此处描述的方法更能解决它们。pthread_join()

即便如此,这可能没有多大帮助。如果你还没有从多个线程中看到至少一些优势(并且你有足够的内核,它们实际上可以同时运行),那么你可能没有足够的总工作来让并行化变得值得。