当只有1个线程主要使用该对象而其他线程很少使用该对象时,如何最小化该对象的互斥锁?

问题描述 投票:6回答:1

场景

假设具有共享的SQLite数据库对象的“ Thread_Main”和“ Thread_DB”。保证,

  • “ Thread_main”很少使用SQLite对象进行读取(即SELECT()
  • “” Thread_DB“大部分时间都使用SQLite对象执行各种INSERTUPDATEDELETE操作

为了避免数据争用和UB,SQLite应该使用SQLITE_THREADSAFE=1(默认)选项进行编译。这意味着在每次操作之前,内部mutex将被锁定,从而使DB在读取时不会写入,反之亦然。

"Thread_Main"    "Thread_DB"    no. of operation on DB
=============    ===========    ======================
something           INSERT             1
something           UPDATE             2
something           DELETE             3
something           INSERT             4
...                   ...             ...         (collapsed)
something           INSERT            500
something           DELETE            501
...                   ...             ...         (collapsed)
something           UPDATE            1000
something           UPDATE            1001
...                   ...             ...         (collapsed)
SELECT              INSERT            1200  <--- here is a serious requirement of mutex
...                   ...             ...         (collapsed)

问题

如上所示,在数百次操作中,仅偶尔需要真正的互斥量。但是,为了保护这种小情况,我们必须为所有操作锁定它。

问题:是否有一种方法可以使“ Thread_DB”在大多数时间保持互斥量,从而不需要每次锁定?仅当“ Thread_Main”请求时才可以进行锁定/解锁。

注意

  • 一种方法是将[Thread_DB]中的SELECT排队。但是在运行多个数据库的较大场景中,这将减慢响应速度,而且不是实时的。无法让主线程等待它。
  • 我还考虑过具有“ Thread_Main”的整数/布尔变量,这将表明“ Thread_Main”想要SELECT。现在,如果那时“ Thread_DB”中正在运行任何操作,则可以解锁互斥锁。这可以。但是,如果在该SQLite对象上没有可写操作正在运行,则“ Thread_main”将一直等待,因为“ Thread_DB”中没有人可以解锁。这将再次延迟甚至挂起“ Thread_Main”。
c++ algorithm qt mutex micro-optimization
1个回答
1
投票

这里是一个建议:对程序进行一些修改,以使Thread_Main对共享库具有no访问权限;只有Thread_DB可以访问它。完成此操作后,您将根本不需要进行任何序列化,并且Thread_DB可以完全有效地工作。

美中不足的是,有时Thread_Main确实需要与DB对象进行交互;如果它无权访问它怎么办?

该问题的解决方案是消息传递。当Thread_Main需要对数据库执行某些操作时,应将某种Message对象传递给Thread_DB。 Message对象应包含表征所需交互的所有必要详细信息。当Thread_DB收到Message对象时,Thread_DB可以调用其execute(SQLite & db)方法(或任何您想调用的方法),这时可以在Thread_DB线程的上下文中进行必要的数据插入/提取。交互完成后,任何结果都可以存储在Message对象内部,然后可以将Message对象传递回主线程,以便主线程处理结果。 (主线程可以阻止等待消息发送回,或者继续与DB线程异步操作,这取决于您)


0
投票

这里是一个建议:对程序进行一些修改,以便Thread_Main对共享库具有no

© www.soinside.com 2019 - 2024. All rights reserved.