-
首页
-
C4D R23.110 C++ SDK
Locks & Synchronization Manual
内容表
关于
Locks are used to guard access to resources that are shared across multiple threads.
-
注意
-
Locks should be used to avoid crashes when seldom used resources are accessed and to protect single threaded operations. Locks should not be used to fix problems of ill-designed code.
-
警告
-
Make sure that a thread releases a lock after it has finished or a deadlock will be the result.
Spinlock
maxon::Spinlock
implements a mutex that will loop on a pause/idle instruction when it is already locked.
// This example shows how a global spin lock is used to protect the access to a global function.
static
maxon::Result<void>
UpdateWithSpinlock()
{
// example global instance; typically a member variable would be used
static
maxon::Spinlock
g_spinlock;
// lock
g_spinlock.
锁
();
// handle shared resource
const
maxon::Result<void>
res = UpdateGlobalData();
// unlock
g_spinlock.
Unlock
();
return
res;
}
ScopedLock
A
maxon::ScopedLock
acquires a lock when created and releases upon destruction (at the end of the scope).
-
警告
-
ScopedLock should only be used for a short block of code. It will block all other threads.
// This example uses a maxon::ScopedLock to protect access to a global function.
static
maxon::Result<void>
UpdateWithScopedLock(
maxon::Spinlock
& lock)
{
iferr_scope
;
// lock on creation
maxon::ScopedLock
scopedLock(lock);
// handle shared resource
return
UpdateGlobalData();
}
RWSpinlock
The
maxon::RWSpinlock
allows access for multiple readers and only one exclusive writer.
// This example shows how a global RW spin lock is used to protect the access to global functions.
// example global instance; typically a member variable would be used
static
maxon::RWSpinlock
g_rwSpinlock;
static
maxon::Result<void>
UpdateWithRWLock()
{
// write lock
g_rwSpinlock.
WriteLock
();
// handle shared resource
const
maxon::Result<void>
res = UpdateGlobalData();
// write unlock
g_rwSpinlock.
WriteUnlock
();
return
res;
}
static
maxon::Int
ReadWithRWLock(
maxon::Int
i)
{
// read lock
g_rwSpinlock.
ReadLock
();
// access shared resource
const
maxon::Int
res = AccessData(i);
// read unlock
g_rwSpinlock.
ReadUnlock
();
return
res;
}
ARWLock
The
maxon::ARWLock
is an asymmetric read write lock which prefers the readers.
// This example shows how a global asymmetric read write lock is used to protect the access to a global function.
// example global instance; typically a member variable would be used
static
maxon::ARWLock
* g_arwlock =
nullptr
;
static
maxon::Result<void>
Init()
{
iferr_scope
;
g_arwlock =
NewObj
(
maxon::ARWLock
)
iferr_return
;
return
maxon::OK
;
}
static
void
Clear()
{
DeleteObj
(g_arwlock);
}
MAXON_INITIALIZATION
(Init, Clear);
static
maxon::Result<void>
UpdateWithARWLock()
{
g_arwlock->
WriteLock
();
const
maxon::Result<void>
res = UpdateGlobalData();
g_arwlock->
WriteUnlock
();
return
res;
}
Synchronized
The
maxon::Synchronized
template is used to guarantee safe access to a given variable. It allows access to the variable only after a lock has been acquired. For asymmetric read-write access there is also
maxon::RWSynchronized
based on
maxon::ARWLock
.
// This example shows an example class that uses
// maxon::Synchronized to lock access to a member variable.
class
SimpleStringClass
{
public
:
// return stored String
maxon::String
GetString()
const
{
return
*_string.Read();
}
// add to stored String
maxon::Result<void>
AddString(
const
maxon::String
&
string
)
{
return
_string.Write()->Append(
string
);
}
// adds multiple strings to the stored String
maxon::Result<void>
AddStrings(
maxon::BaseArray<maxon::String>
& strings)
{
iferr_scope
;
// get locked pointer to get write access
auto
lockedPtr = _string.Write();
for
(
maxon::String
& str : strings)
{
lockedPtr->Append(str)
iferr_return
;
}
// lock on _string is released when the function scope is left
return
maxon::OK
;
}
private
:
maxon::Synchronized<maxon::String>
_string;
};
Serializer
The
maxon::Serializer
guarantees mutually exclusive access to a shared resource. The given lambdas are enqueued and executed.
-
注意
-
maxon::Serializer
is low level and does not support error handling.
// This example uses the given Serializer to manage access to a shared resource.
g_serializer.EnqueueAndWait([]()
{
iferr
(UpdateGlobalData())
{
DiagnosticOutput
(
"Error in UpdateGlobalData()"
);
}
});
延伸阅读
void Lock()
定义:
spinlock.h:86
void WriteLock()
定义:
arwlock.h:66
#define DeleteObj(obj)
定义:
newobj.h:159
return OK
定义:
apibase.h:2532
#define iferr_return
定义:
resultbase.h:1434
void Unlock()
定义:
spinlock.h:97
void WriteUnlock()
定义:
arwlock.h:76
#define DiagnosticOutput(formatString,...)
定义:
debugdiagnostics.h:166
#define MAXON_INITIALIZATION(...)
定义:
module.h:735
Int64 Int
signed 32/64 bit int, size depends on the platform
定义:
apibase.h:184
#define iferr_scope
定义:
resultbase.h:1343
#define NewObj(T,...)
定义:
newobj.h:108
#define iferr(...)
定义:
errorbase.h:380