In Hazelcast, is it possible to use clustered locks that do _not_ care about the local thread that performs the lock/unlock operations? - locking

Hazelcast locks (such as http://www.hazelcast.com/docs/1.9.4/manual/multi_html/ch02s07.html) as I understand it behave the same way as the Java concurrency primitives but across the cluster. The makes it possible to use to synchronize between thread in the local process as well as over the cluster.
However, is there any way I can opt out of this behaviour? In my current project, I need a way of coordinating unique ownership of a resource across the cluster but want to aquire and release this ownership from multiple points in my application - can I do this in some way that does not involve dedicating a thread to managing this lock in my process?

The Semaphore is your friend because it doesn't have a concept of ownership. It uses permits that can be acquired; thread x can acquire permit 1, but thread y can release permit 1. If you initialize the semaphore with a single permit, you will get your mutual exclusion.
ISemaphore s = hazelcastInstance.getSemaphore("foo");
s.init(1);
s.acquire();
And in another thread you can release this permit by:
ISemaphore s = hazelcastInstance.getSemaphore("foo");
s.release();

Related

What problem does the redis distributed lock solve?

So I just read about redlock. What I understood is that it needs 3 independent machines to work. By independent they mean that all the machines are masters and there is no replication amongst them, which means they are serving different types of data. So why would I need to lock a key present in three independent redis instances acting as masters ? What are the use cases where I would need to use redlock ?
So why would I need to lock a key present in three independent redis instances acting as masters?
It's not that you're locking a key within Redis. Rather, the key is the lock, and used to control access to some other resource. That other resource could be anything, and generally is something outside of Redis since Redis has its own mechanisms for allowing atomic access to its data structures.
What are the use cases where I would need to use redlock?
You would use a distributed lock when you want only one member at a time of a distributed system to do something.
To take a random example from the internet, here's Coinbase talking about their use of a distributed lock to "ensure that multiple processes do not concurrently generate and broadcast separate transactions to the network".

Should one minimize the number of command pools an application creates?

Say that there is a queue family which supports presentation to a surface, and graphics. Is it better (due to technical reasons) to create a single command pool which handles presentation and graphics, or is it better to create two command pools: one the application will use only for graphics (even though it could use it for presentation) and another the application will use only for presentation (even though it could use it for graphics)?
Essentially, should one minimize the number of command pools associated with a particular queue family? Or is it okay to create as many command pools as one desires? More generally (regardless of which queue family the command pools are associated with), should an application minimize how many command pools it creates?
EDIT: I wrote "queues" instead of "command pools" in the initial version of this post. This has been fixed.
The main purpose of a command pool is to be a (mostly) single-threaded allocator for the storage used by a set of command buffers which are filled by that thread. You create pools to serve that purpose.
So if you have three threads that need to generate commands for a particular queue, then you create 3 pools, one for each such thread, and use them to generate the CBs you are interested in.
And depending on your CB resetting strategy, you may want to multi-buffer pools. That is, while a thread is generating commands into CBs from pool A, the GPU is reading from CBs from pool B. That way, when the GPU is done, you can just reset the pool rather than resetting the individual CBs.
The overall point is that you create command pools to serve your application's allocation and CB-building strategy. The association of a pool with a queue family is there solely to help the implementation generate commands for those CBs more efficiently. You should not assume that a pool is consuming some kind of limited resource from the queue.

Is it allowed to record CommandBuffers on multiple threads which were allocated from the same pool?

Suppose we have a CommandPool with two CommandBuffers allocated from it (CommandBuffer1, CommandBuffer2).
The CommandPool lives on Thread 0, CommandBuffer1 and CommandBuffer2 also live on Thread 0.
Is it possible to transfer CommandBuffer1 and CommandBuffer1 to a different thread to record commands? With the restriction that only one thread is allowed the record a CommandBuffer at the same time?
The spec states
Command pools are application-synchronized, meaning that a command pool must not be used concurrently in multiple threads. That includes use via recording commands on any command buffers allocated from the pool, as well as operations that allocate, free, and reset command buffers or the pool itself.
I am not quite sure if I would be allowed to record CommandBuffer1 on Thread 1 and CommandBuffer2 on Thread 2 at the same time.
Or do I have to record all CommandBuffers on the same thread that they were allocated from?
There is a list of "Implicit Externally Synchronized Parameters" in chapter 2.5. Threading Behavior that has a list mostly consisting of:
The VkCommandPool that commandBuffer was allocated from, in vkCmd*
So no it's not possible to record 2 command buffers from the same pool on different threads.
Though it is strange that vkBeginCommandBuffer and vkEndCommandBuffer isn't in that list.
Who's forcing you to have only one pool though?
Have one pool per thread. Problem solved.
Yes, you do not have to use them on the same thread. You just must make sure that:
[...]command pool must not be used concurrently in multiple threads.
If you (for some obscure reason) want to use the pool on different thread, you must stop using it on the original thread (via using synchronization primitives) before you start using it on the second thread.

how to design multi-process program using redis in python

I just started to use the redis cache in python. I read the tutorial but still feel confused about the concepts of "connectionpool", "connection" and etc..
I try to write a program which will be invoked multiple times in the console in different processes. They will all get and set the same shared in memory redis cache using same set of keys.
So to make it thread(process) safe, should I have one global connectionpool and get connections from the pool in different processes? Or should I have one global connection? What's the right way to do it?
Thanks,
Each instance of the program should spawn its own ConnectionPool. But this has nothing to do with thread safety. Whether or not your code is thread safe will depend on the type of operations you will be executing, and if you have multiple instances which may read and write concurrently, you need to look into using transactions, which are built into redis.

Servlet design, concurrent access to field

I have rather general question, please advice.
I have a servlet.
This servlet has private field.
Private field is a kind of metadata stuff (public class Metadata{//bla-bla-bla}).
When GET request is processed, this metadata is used to perform some operation.
I want to implement POST method in the same servlet. User uploads file and Metadata field is updated.
The problem: concurrent access to this private field with Metadata object shared among sereval web-threads using one servlet instance. POST method operaton (Update Metadata object) can lead to Metadata inconsistent state and concurrent GET request can be failed.
The question: what is the best way to update Metadata object while GET requests are running?
Dummy solution:
During each GET request,, at the very beginning
Synchonize Metadata object and clone it in one block, then release it.
Concurrent GET requests work with clone verstion of Metadata object which is consistent.
During each POST request.
Synchonize Metadata object and update its fields.
Release Metadata object.
Please advice or critisize.
Using synchronized methods set and get in the Metadata class is fine but may slower your web app in case you have multiple readers and (much) less writers:
Java synchronized keyword is used to acquire a exclusive lock on an
object. When a thread acquires a lock of an object either for reading
or writing, other threads must wait until the lock on that object is
released. Think of a scenerio that there are many reader threads that reads a shared
data frequently and only one writer thread that updates shared data.
It’s not necessary to exclusively lock access to shared data while
reading because multiple read operations can be done in parallel
unless there is a write operation.
(Excerpt from that nice post)
So using a multiple read single write strategy may be better in term of performance in some cases as explained also in the same Java5 ReadWriteLock interface doc:
A read-write lock allows for a greater level of concurrency in
accessing shared data than that permitted by a mutual exclusion lock.
It exploits the fact that while only a single thread at a time (a
writer thread) can modify the shared data, in many cases any number of
threads can concurrently read the data (hence reader threads). In
theory, the increase in concurrency permitted by the use of a
read-write lock will lead to performance improvements over the use of
a mutual exclusion lock. In practice this increase in concurrency will
only be fully realized on a multi-processor, and then only if the
access patterns for the shared data are suitable.
Whether or not a read-write lock will improve performance over the use
of a mutual exclusion lock depends on the frequency that the data is
read compared to being modified, the duration of the read and write
operations, and the contention for the data - that is, the number of
threads that will try to read or write the data at the same time. For
example, a collection that is initially populated with data and
thereafter infrequently modified, while being frequently searched
(such as a directory of some kind) is an ideal candidate for the use
of a read-write lock. However, if updates become frequent then the
data spends most of its time being exclusively locked and there is
little, if any increase in concurrency. Further, if the read
operations are too short the overhead of the read-write lock
implementation (which is inherently more complex than a mutual
exclusion lock) can dominate the execution cost, particularly as many
read-write lock implementations still serialize all threads through a
small section of code. Ultimately, only profiling and measurement will
establish whether the use of a read-write lock is suitable for your
application.
A ready to use implementation is the ReentrantReadWriteLock.
Take a look at the previous post for a nice tutorial on how to use it.