- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在实现一对用于进程间通信的类,其中一个进程将是唯一的写入者,并且会有很多读取者。一类处理阅读;一个负责写作。为了防止任何其他进程成为编写器,我想要一个编写器类的单个对象,它在 boost::named_upgradable_mutex
的整个生命周期内保持一个可升级的锁。为此,writer 类有一个 boost::interprocess::upgradable_lock
类型的成员变量,在构造对象时将其传递给互斥量。当编写器进程写入时,它会调用编写器类的 Write() 方法,该方法应将该锁升级为独占锁,执行写入,并以原子方式将独占锁再次降级为仅可升级。
我已按照 Lock Transfers Through Move Semantics 上的 Boost 文档,在我的编写器类的 Write() 方法中成功实现了第一部分——将锁升级为独占锁。 .然而,第二部分 - 将锁降级为可升级 - 导致类型为 boost::interprocess::upgradable_lock 的新局部变量,它将超出范围并在 Write() 返回时释放互斥锁。我需要将该可升级锁放回我类的 upgradable_lock 成员变量中,以便升级功能将仅保留在我的 writer 对象中。最好的方法是什么?我设法想出的唯一一件事是在返回之前用我的成员变量交换局部变量。代码如下所示:
using boost::interprocess;
scoped_lock<named_upgradable_mutex> my_exclusive_lock(move(m_lock));
// do write here
upgradable_lock<named_upgradable_mutex> my_demoted_lock(move(my_exclusive_lock));
m_lock.swap(my_demoted_lock); // how else to do this?
这行得通,但最后一行确实违反直觉,让我花了一些时间来思考。有没有更好的办法?是否可以将降级锁直接放入我的成员变量中?另外,重用成员变量存储降级锁是否有任何意想不到的后果?
最佳答案
考虑使用 move assignment operator .以下代码使用 swap()
:
upgradable_lock<named_upgradable_mutex> my_demoted_lock(move(my_exclusive_lock));
m_lock.swap(my_demoted_lock);
会变成:
m_lock = upgradable_lock<named_upgradable_mutex>(move(my_exclusive_lock));
在这种特殊情况下,swap()
和移动赋值运算符可以互换,没有任何副作用,因为 m_lock
处于默认构造状态 (m_lock. owns() == false
和 m_lock.mutex() == 0
)。
我想不出为可升级锁重用成员变量有任何意想不到的后果。但是,有几个主题需要考虑:
一个目标是“防止任何其他进程成为写入者”。通过在 Writer
构造函数中获取锁,除了防止其他进程 creating Writer
代码之外em>写作。因此,阻塞调用可能对应用程序代码造成影响或带来不便。考虑以下代码:
Reader reader;
Writer writer; // This may block, but the application code cannot react
// to it without dedicating an entire thread to the
// construction of the writer.
一个妥协的选择可能是尝试通过this constructor获取锁,然后向 Writer
添加成员函数,为应用程序提供更多控制。虽然这仍将允许其他进程创建一个 Writer
,但它会阻止多个进程拥有写入权限:
class Writer
{
public:
bool IsPrivileged(); // Returns true if this the privileged Writer.
bool TryBecomePrivileged(); // Non-blocking attempt to become the
// privileged Writer. Returns true on success.
bool BecomePrivileged(); // Blocks waiting to become the privileged
// Writer. Returns true on success.
void RelinquishPrivileges(); // We're not worthy...we're not worthy...
enum Status { SUCCESS, NOT_PRIVILEGED };
Status Write( const std::string& ); // If this is not the privileged Writer,
// then attempt to become it. If the
// attempt fails, then return
// NOT_PRIVILEGED.
};
在 Writer::Write()
方法中,如果“do write here”代码中的任何调用抛出异常,则堆栈将放松,导致:
my_exclusive_lock
释放独占锁,允许其他进程获得可升级锁。m_lock
没有互斥量的句柄,因为当所有权转移到 时 m_lock.mutex()
设置为 null
>my_exclusive_lock
在 move .Writer::Write()
将尝试写入 而不 获取独占锁!即使 m_lock
有互斥量的句柄,m_lock.owns()
也会是 false
,所以转移到 my_exclusive_lock
不会尝试锁定。这是一个示例程序:
#include <boost/interprocess/sync/named_upgradable_mutex.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <boost/interprocess/sync/upgradable_lock.hpp>
#include <boost/move/move.hpp>
#include <iostream>
int main()
{
namespace bip = boost::interprocess;
typedef bip::named_upgradable_mutex mutex_t;
struct mutex_remove
{
mutex_remove() { mutex_t::remove( "example" ); }
~mutex_remove() { mutex_t::remove( "example" ); }
} remover;
// Open or create named mutex.
mutex_t mutex( bip::open_or_create, "example" );
// Acquire upgradable lock.
bip::upgradable_lock< mutex_t > m_lock( mutex, bip::try_to_lock );
std::cout << "upgradable lock own: " << m_lock.owns()
<< " -- mutex: " << m_lock.mutex()
<< std::endl;
// Acquire the exclusive lock.
{
std::cout << "++ Entering scope ++" << std::endl;
std::cout << "Transferring ownership via move: Upgradable->Scoped"
<< std::endl;
bip::scoped_lock< mutex_t > exclusive_lock( boost::move( m_lock ) );
std::cout << "upgradable lock owns: " << m_lock.owns()
<< " -- mutex: " << m_lock.mutex()
<< "\nexclusive lock owns: " << exclusive_lock.owns()
<< " -- mutex: " << exclusive_lock.mutex()
<< std::endl;
// do write here...
// Demote lock from exclusive to just an upgradable.
std::cout << "Transferring ownership via move: Scoped->Upgradable"
<< std::endl;
m_lock = bip::upgradable_lock< mutex_t >( boost::move( exclusive_lock ) );
std::cout << "upgradable lock owns: " << m_lock.owns()
<< " -- mutex: " << m_lock.mutex()
<< "\nexclusive lock owns: " << exclusive_lock.owns()
<< " -- mutex: " << exclusive_lock.mutex()
<< std::endl;
std::cout << "-- Exiting scope --" << std::endl;
}
std::cout << "upgradable lock own: " << m_lock.owns()
<< " -- mutex: " << m_lock.mutex()
<< std::endl;
return 0;
}
产生以下输出:
upgradable lock own: 1 -- mutex: 0xbff9b21c++ Entering scope ++Transferring ownership via move: Upgradable->Scopedupgradable lock owns: 0 -- mutex: 0exclusive lock owns: 1 -- mutex: 0xbff9b21cTransferring ownership via move: Scoped->Upgradableupgradable lock owns: 1 -- mutex: 0xbff9b21cexclusive lock owns: 0 -- mutex: 0-- Exiting scope --upgradable lock own: 1 -- mutex: 0xbff9b21c
关于c++ - 如何在对象的生命周期内保持 Boost upgradable_lock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10537077/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!