I am trying to implement a thread safe queue using a Semaphore that is enqueued with integers. This is not thread-safe at the moment. What would I have to add in terms of synchronization to the queue to make it thread-safe?
I've tried using synchronized blocks on the Queue, so that only one thread is allowed in the queue at the same time, but this does not seem to work, or I am misusing them. What should I be synchronizing on? I have a separate class that is constantly appending and removing with a maintainer thread.
class ThreadSafeQueue {
var queue = List[Int]()
val semaphore = new Semaphore(0)
def append(num: Int): Unit = {
queue = queue ::: List(num)
semaphore.release()
}
def dequeue(): Int = {
semaphore.acquire()
val n = queue.head
queue = queue.tail
n
}
}
To be thread-safe, you should place code that accesses the queue in synchronized blocks, as shown below.
import java.util.concurrent.Semaphore
class ThreadSafeQueue {
var queue = List[Int]()
val semaphore = new Semaphore(0)
def append(num: Int): Unit = {
synchronized {
queue = queue ::: List(num)
}
semaphore.release()
}
def dequeue(): Int = {
semaphore.acquire()
synchronized {
val n = queue.head
queue = queue.tail
n
}
}
}
A few notes:
With the Semaphore permits value set to 0, all acquire() calls will block until there is a release().
In case the Semaphore permits value is > 0, method dequeue would better be revised to return an Option[Int] to cover cases of dequeueing an empty queue.
In case there is only a single queue in your application, consider defining ThreadSafeQueue as object ThreadSafeQueue.
There is an arguably more efficient approach of atomic update using AtomicReference for thread-safety. See this SO link for differences between the two approaches.
Related
This is a sample batch processing application. Initially I do create a thread pool for the batch processing and then execute those threads on the batching. Once the batch processing is started, it is keep looping and searching for entries in the queue for batching. That is a huge performance drain and the CPU usage goes to max.
The following block contains the sample code, I am currently working on.
BlockingQueue<BatchRequestEntry> batchingQueue;
ThreadPoolExecutor executorService executorService;
private boolean isRunning = false;
private ExecutorService getExecutorService() {
if (executorService == null) {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("batch-processor-%d").build();
executorService = new ThreadPoolExecutor(batchProcessorConfiguration.getThreadCount(), batchProcessorConfiguration.getThreadCount(),
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(), threadFactory);
}
return executorService;
}
public synchronized void start() {
if (isRunning) {
return;
}
getExecutorService().submit(() -> {
while (isRunning) {
if (!batchingQueue.isEmpty()) {
List<BatchRequestEntry> entries = batchingQueue.batch(batchProcessorConfiguration.getBatchingMaxCount());
executorService.submit(() -> process(entries));
}
}
});
isRunning = true;
}
public SettableFuture<BatchResultEntry> append(BatchRequestEntry batchRequestEntry) {
if (!isRunning) {
start();
}
SettableFuture<BatchResultEntry> future = SettableFuture.create();
batchingQueue.append(batchRequestEntry);
futures.put(batchRequestEntry.getEntryId(), future);
return future;
}
What I want to provide as a solution is to capture the number of loops with empty batching queue. Then compare that value with a threshold value and sleep the threads in the thread pool. Once the new entries are appended to the batching queue, I want to interrupt the thread sleep and continue the loop for batching. I think that would solve the problem.
I want to figure how to do that with ThreadPoolExecutor and I would appreciate if there are better approaches to address this problem. Thank you!
It is easy enough in D to create a Queue type using the std.container.dlist.
I would like to have multiple threads but have them communicate with a queue, not with message passing (https://tour.dlang.org/tour/en/multithreading/message-passing). As I understand it the messages are designed to always receive data at particular points in the code; the receiving thread will block until the expected data is received.
(EDIT: I was informed about receiveTimeout but having a no timeout and just a check is really more appropriate in this case (maybe a timeout of 0?). Also I am not sure what the message API will do if multiple messages are sent before any any are received. I will have to play with that.)
void main() {
spawn(&worker, thisTid);
// This line will block until the expected message is received.
receive (
(string message) {
writeln("Received the message: ", text);
},
)
}
What I am needing is to merely receive data if there is some. Something like this:
void main() {
Queue!string queue// custom `Queue` type based on DList
spawn(&worker, queue);
while (true) {
// Go through any messages (while consuming `queue`)
for (string message; queue) {
writeln("Received a message: ", text);
}
// Do other stuff
}
}
I have tried using shared variables (https://tour.dlang.org/tour/en/multithreading/synchronization-sharing) but DMD is complaining that "Aliases to mutable thread-local data not allowed." or some other errors, depending.
How would this be done in D? Or, is there a way to use messages to do this kind of communication?
This doesn't answer the specific question but ti does clear up what I think is a misunderstanding of the message passing api...
just call receiveTimeout instead of plain receive
http://dpldocs.info/experimental-docs/std.concurrency.receiveTimeout.html
I use this:
shared class Queue(T) {
private T[] queue;
synchronized void opOpAssign(string op)(T object) if(op == "~") {
queue ~= object;
}
synchronized size_t length(){
return queue.length;
}
synchronized T pop(){
assert(queue.length, "Please check queue length, is 0");
auto first = queue[0];
queue = queue[1..$];
return first;
}
synchronized shared(T[]) consume(){
auto copy = queue;
queue = [];
return copy;
}
}
I have gotten the answer I need.
Simply put, use core.thread rather than std.concurrency. std.concurrency manages messages for you and does not allow you to manage it yourself. core.thread is what std.concurrency uses internally.
The longer answer, here is how I fully implemented it.
I have created a Queue type that is based on an Singly Linked List but maintains a pointer of the last element. The Queue also uses standard component inputRange and outputRange (or at least I think it does) per Walter Brights vision (https://www.youtube.com/watch?v=cQkBOCo8UrE).
The Queue is also built to allow one thread to write and another to read with very little mutexing internally so it should be fast.
The Queue I shared here https://pastebin.com/ddyPpLrp
A simple implementation to have a second thread read input:
Queue!string inputQueue = new Queue!string;
ThreadInput threadInput = new ThreadInput(inputQueue);
threadInput.start;
while (true) {
foreach (string value; inputQueue) {
writeln(value);
}
}
ThreadInput being defined as thus:
class ThreadInput : Thread {
private Queue!string queue;
this(Queue!string queue) {
super(&run);
this.queue = queue;
}
private void run() {
while (true) {
queue.put(readln);
}
}
}
The code https://pastebin.com/w5jwRVrL
The Queue again https://pastebin.com/ddyPpLrp
I have a dictionary with a custom class object as key and a class queue
ConcurrentDictionary<clsEFTOPConnection, Queue<clsEFTOPS>>();
here clsEFTOPConnection and clsEFTOPS are custom classes. I add a new queue if it is not in the dictionary. Now I want to work parallelly on each queue. I want each queue to be watched by threads and whenever a enqueue operation is performed, the particular thread should awake if sleeping and start dequeuing items. So no of threads is equal to no of queues and each thread will act as a watcher of its queue.
I have written below code to achieve it, but it's not functioning as per my needs
public Queue<clsEFTOPS> CheckAlreadyExistingQueue(clsEFTOPConnection objEFTOPConnection, clsEFTOPS objJobQ)
{
Queue<clsEFTOPS> queue;
// See if we have a queue
if (!mHostQueues.TryGetValue(objEFTOPConnection, out queue))
{
// No queue for this Host, so create and cache
queue = new Queue<clsEFTOPS>();
objJobQ.Host = objEFTOPConnection.Host;
objJobQ.PortNo = objEFTOPConnection.PortNo;
objEFTOPConnection.socket_ = objJobQ.ReconnectSocket();
queue.Enqueue(objJobQ);
mHostQueues.TryAdd(objEFTOPConnection, queue);
JobThrd = new Thread(() => DequeueJobs(queue, objEFTOPConnection));
if (JobThrd.ThreadState != ThreadState.Running)
JobThrd.Start();
}
else
{
queue.Enqueue(objJobQ);
if (queue.Count > 1)
JobThrd = new Thread(() => DequeueJobs(queue, objEFTOPConnection));
else
DequeueJobs(queue, objEFTOPConnection);
if (JobThrd.ThreadState != ThreadState.Running)
JobThrd.Start();
}
return queue;
}
I have a function(be it a static function or totally unaffiliated one) and a specific thread
class AnyClass{
static func foo(myThread: NSThread) {
....
// I want this *blablabla* to be performed on myThread
....
}
}
How can I make is happen?
Don't use thread, use dispatch queue (Grand Central Dispatch) instead. See Apple's documentation on Migrating away from threads.
A typical usage pattern for GCD is:
class AnyClass{
static func foo(queue: dispatch_queue_t) {
....
let group = dispatch_group_create();
dispatch_group_enter(group) // tell the OS your group has started
dispatch_group_async(group, queue) {
// Do your things on a different queue
....
dispatch_group_leave(group) // tell the OS your group has ended
}
// Do your other things on the original thread simultaneously
....
dispatch_group_wait(group, DISPATCH_TIME_FOREVER) // wait for the queue to finish
// Do other things still
....
}
}
// Calling the function
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
AnyClass.foo(queue)
I think I got this wrong from the docs.
I have two actors, XMLActor and HttpActor. XMLActor reads xmlFiles and then sends a message to HTTPActor to process. XMLActor will finish way sooner than HttpActor.
My main class calls join on both actors. I was expecting that the main thread would only terminate after both actors were done. But, what is actually happening is that as soon as all messages are processed by XMLActor, the system terminates and a lot of messages are not processed by HttpActor.
I could use some latch or even an AtomicInteger to wait for all messages to be consumed, but I was wondering if there's a more elegant way for it.
final HttpActor httpActor = new HttpActor().start()
final XMLActor xmlActor = new XMLActor(httpActor:httpActor).start()
Actors.actor {
file.eachLine { line ->
def chunks = line.split(",")
def id = chunks[0].replaceAll("\\\"","").trim()
def name = chunks[1].replaceAll("\\\"","").trim()
xmlActor << new FileToRead(basePath:args[1],id:id,name:name, fileCounter:counter)
}
}
[httpActor, xmlActor]*.join()
//inside xmlActor
countries.each { country ->
httpActor << new AlbumPriceMessage(id:message.id, country:country)
}
The join() method will certainly wait for both actors to finish. I don't see how you stop the two actors, so can't really comment on that. Do you send so sort of poison message? Or call stop() on actors?
For example, the following simulation of your case stops correctly:
import groovyx.gpars.actor.*;
def httpActor = Actors.staticMessageHandler {
println "Http actor processing " + it
}
def xmlActor = Actors.staticMessageHandler {
println "XML Actor processing " + it
httpActor << it
}
xmlActor.metaClass.afterStop = {
httpActor.stop()
}
100.times {
xmlActor << "File$it"
}
xmlActor.stop()
[xmlActor, httpActor]*.join()
println "done"