There are two threads T1 and T2
class Sender{
public:
void sendMessage();
};
class Reciever{
public:
void getMessage(string msg);
};
Consider Sender S is in Thread T1, Reciever R is in Thread T2 and now I need S.sendMessage() should communicate with object R to execute getMessage(string msg). So how can I do it... Producer and consumer approach might help but here it is a one-time requirement so is that really neede to maintain a common queue? please help me.
Condition variables are what you are looking for. They allow a thread to wait (blocking) for an event sent from another thread.
You correctly discerned that you do not need a producer-consumer queue if there is only one producer and only one consumer and only a single message is passed.
So, your receiver thread calls getMessage (which should either return a string, or take the string as a reference parameter), which internally waits for a condition variable. Then, in the sender thread, you notify the condition variable inside sendMessage. This wakes up the receiver thread.
Edit: Although you are asking a pthread-specific question, pthread has an equivalent of C++'s std::condition_variable. I recommend you use C++11's utilities instead of talking to pthreads directly, as they are easier to use.
Edit 2: You cannot just make another thread execute some function. The only thing you can do between threads is communication, so if you want to have some reaction in another thread to something you do in your thread, the other thread has to be actively waiting for you to trigger this event (by notifying a condition variable or similar).
The standard way combines a std::queue with a mutex and a condition variable. The mutex is used by the condition variable and protects the queue. The receiver waits until the queue is not empty and then pops the message from the queue. The sender pushes the message onto the queue.
When only one type of message is needed, you can use a queue of messages, if not then make it dynamic by sending shared pointers to messages.
Related
Due to fixed requirements, I need to execute some code in a specific thread, and then return a result. The main-thread initiating that action should be blocked in the meantime.
void background_thread()
{
while(1)
{
request.lock();
g_lambda();
response.unlock();
request.unlock();
}
}
void mainthread()
{
...
g_lambda = []()...;
request.unlock();
response.lock();
request.lock();
...
}
This should work. But it leaves us with a big problem: background thread needs to start with response mutex locked, and main-thread needs to start with request mutex locked...
How can we accomplish that? I cant think of a good way. And isnt that an anti-pattern anyways?
Passing tasks to background thread could be accomplished by a producer-consumer queue. Simple C++11 implementation, that does not depend on 3rd party libraries would have std::condition_variable which is waited by the background thread and notified by main thead, std::queue of tasks, and std::mutex to guard these.
Getting the result back to main thread can be done by std::promise/std::future. The simplest way is to make std::packaged_task as queue objects, so that main thread creates packaged_task, puts it to the queue, notifies condition_variable and waits on packaged_task's future.
You would not actually need std::queue if you will create tasks by one at once, from one thread - just one std::unique_ptr<std::packaged_task>> would be enough. The queue adds flexibility to simultaneosly add many backround tasks.
I am in process of implementing messages passing from one thread to another
Thread 1: Callback functions are registered with libraries, on callback, functions are invoked and needs to be send to another thread for processing as it takes time.
Thread 2: Thread to check if any messages are available(preferrednas in queue) and process the same.
Is condition_variable usage with mutex a correct approach to start considering thread 2 processing takes time in which multiple other messages can be added by thread 1?
Is condition_variable usage with mutex a correct approach to start considering thread 2 processing takes time in which multiple other messages can be added by thread 1?
The question is a bit vague about how a condition variable and mutex would be used, but yes, there would definitely be a role for such objects. The high-level view would be something like this:
The mutex would protect access to the message queue. Any read or modification of the queue, by any thread, would be done only while holding the mutex locked.
The message-processing thread would block on the CV in the event that it became ready to process a new message but the queue was empty.
The message-generating thread would signal the CV each time it enqueued a new message.
This is exactly a producer / consumer problem, and you can find a lot of information about such problems using that terminology.
But note also that there are multiple message queue implementations already available to serve exactly your purpose ("message queue" is in fact a standard term for these), so you should consider whether you really want to reinvent this wheel.
In general, mutexes are intended to control access between threads; but not great for notifying between threads.
If you design Thread2 to wait on the condition; you can simply process messages as they are received from Thread1.
Here would be a rough implementation
void pushFunction
{
// Obtain the mutex (preferrably scoped lock in boost or c++17)
std::lock_guard lock(myMutex);
const bool empty = myQueue.empty();
myQueue.push(data);
lock.unlock();
if(empty)
{
conditionVar.notify_one();
}
}
In Thread 2
void waitForMessage()
{
std::lock_guard lock(myMutex);
while (myQueue.empty())
{
conditionVar.wait(lock);
}
rxMessage = myQueue.front();
myQueue.pop();
}
It's important to note that the condition can spuriously wake up so it's important to keep it in the 'while empty' loop.
See https://en.cppreference.com/w/cpp/thread/condition_variable
Is there any event mechanism or predefined signals in the queue. If any data or message comes in the queue the queue should generate an event saying data is ready to process. Or signal other thread to do his task Instead of continuously polling to the queue.
In posix Message Queue there is function like mq_notify() which will notify to other process or thread if any data comes in the Message queue so we can avoid Polling.
Edit
If not, So how can I achieve this on std::queue. I want to avoid polling continuously it is slowing down the performance of the code.
Whenever some event occur on the queue it should notify to others.
std::queue is a containter type, not an event mechanism. I recommend making a class around the queue that implements a message queue.
EDIT:
Ok, so
So I recommend using an std::queue, std::mutex, and a std::condition_variable, if you use boost that has the same types. Putting those in your new Queue class and when pushing, you would lock the mutex, push onto the queue, unlock the mutex, and notify_one() the condition. That way the condition variable is notified only when pushed. You can do the same on pop.
There are two approaches to this. The simplest is to have an asynchronous queue, implemented using a mutex and condition variable, on which a thread blocks, waiting for another thread to push something onto the queue. This is a very common idiom for task dispatching and here are two simple implementations:
http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html and
http://cxx-gtk-utils.sourceforge.net/2.2/classCgu_1_1AsyncQueueDispatch.html
By using a list rather than a deque as the queue container you can allocate new nodes outside the queue's mutex which significantly improves performance under high contention (see the source code for the second link mentioned above for an example using std::list::splice to achieve this).
Instead of having a designated thread block on the asynchronous queue, after a thread places an item on the queue it could instead invoke an event in the program's event loop which executes a callback which extracts the item from the queue and does something with it. Implementing this is more OS-specific but see http://www.appinf.com/docs/poco/Poco.NotificationQueue.html and http://cxx-gtk-utils.sourceforge.net/2.2/classCgu_1_1Notifier.html for different approaches to this.
I have a C++ application which has the following structure:
Class AAA: has some functions and one of them function that opens a thread.
Class BBB: has some functions and one of them function that opens a thread.
Class CCC: call AAA and BBB that both internaly in their functions open the treads.
In AAA thread in some case I know something that I want to exit the tread and notify both BBB and CCC.
because I am in a thread (Win32Thread) it is a void function I am running in the thread, so I can't return a value to CCC.
I'm new to C++ (coming from c# area) and don't know what is the way to do it. (the notification)
note: I can't change this structure. I can only add or do minor changes in the function of the classes. it is a big process that running in the treads and large code.
Any idea? not a dirty one please, if it possible :)
adding a sample will help me very much.
I don't understand too much your problem, is a bit too generic.
And you didn't specify what kind of multithreading libraries are you using.
To send messages between threads usually Message Queues are used, with wait handles, lock and semaphores to synchornize them.
Of course you need a safe multithreading queue to send your messages between threads.
One possible solution:
If thread A need to send a message to thread B by enqueueing it into thread B queue, waking it up if it is in idle state through a wait event for example.
Thread B receives the message and respond posting another message in A queue.
Another possible solution:
Thread A need to send a message to thread B and need a reply, blocking thread A until the reply is not received.
Thread A enqueue a message in thread B queue, the message object can be in the function stack. Then he wakes up thread B if it is in idle state and then enters in a wait state through a wait handle or a semaphore for example.
Thread B, when dequeues the message, write the answer in the object sent by thread A and wakes up thread A from its awaiting state.
The object field should be marked as volatile because is accessed for read\write by two threads.
Then thread A uses the value stored in message object and delete the object from the stack.
Sounds complicated written in words but the implementation is quite straightforward.
If you are in Windows OS you can just use windows message queue creating invisible message windows, one for each thread. Use PostMessage for the first case, SendMessage for the second case.
If you're not afraid of a Windows-specific solution: call PeekMessage() from BBB thread. This will create a Windows message queue for it. (The main thread already has one). Now, you can use SendMessage() to send a message from AAA to the other threads. Note that you are sending to threads, not classes. Any call to GetMessage() will see your messages.
the typical design I use for threads is a thread function that is passed an instance of the class that contains it (which also holds the instance variables for that thread). Is this the case for you? Does the thread have some instance of a class passed into it? if they do, then just keep track of those from the outside and put BOOL properties that flag when to stop. In the main loops of the threads you just check the flag to see if you have any business looping around again. This is the only clean way to exit a thread.
I am working on a networking program using C++ and I'd like to implement a pthread pool. Whenever, I receive an event from the receive socket, I will put the data into the queue in the thread pool. I am thinking about creating 5 separate threads and will consistently check the queue to see if there is anything incoming data to be done.
This is quite straight forward topic but I am not a expert so I would like to hear anything that might help to implement this.
Please let me know any tutorials or references or problems I should aware.
Use Boost.Asio and have each thread in the pool invoke io_service::run().
Multiple threads may call
io_service::run() to set up a pool of
threads from which completion handlers
may be invoked. This approach may also
be used with io_service::post() to use
a means to perform any computational
tasks across a thread pool.
Note that all threads that have joined
an io_service's pool are considered
equivalent, and the io_service may
distribute work across them in an
arbitrary fashion.
Before I start.
Use boost::threads
If you want to know how to do it with pthread's then you need to use the pthread condition variables. These allow you to suspend threads that are waiting for work without consuming CPU.
When an item of work is added to the queue you signal the condition variable and one pthread will be released from the condition variable thus allowing it to take an item from the queue. When the thread finishes processing the work item it returns back to the condition variable to await the next piece of work.
The main loop for the threads in the loop should look like this;
ThreadWorkLoop() // The function that all the pool threads run.
{
while(poolRunnin)
{
WorkItem = getWorkItem(); // Get an item from the queue. This suspends until an item
WorkItem->run(); // is available then you can run it.
}
}
GetWorkItem()
{
Locker lock(mutex); // RAII: Lock/unlock mutex
while(workQueue.size() == 0)
{
conditionVariable.wait(mutex); // Waiting on a condition variable suspends a thread
} // until the condition variable is signalled.
// Note: the mutex is unlocked while the thread is suspended
return workQueue.popItem();
}
AddItemToQueue(item)
{
Locker lock(mutex);
workQueue.pushItem(item);
conditionVariable.signal(); // Release a thread from the condition variable.
}
Have the receive thread to push the data on the queue and the 5 threads popping it. Protect the queue with a mutex and let them "fight" for the data.
You also want to have a usleep() or pthread_yield() in the worker thread's main loop
You will need a mutex and a conditional variable. Mutex will protect your job queue and when receiving threads add a job to the queue it will signal the condition variable. The worker threads will wait on the condition variable and will wake up when it is signaled.
Boost asio is a good solution.
But if you dont want to use it (or cant use it for whatever reasons) then you'll probably want to use a semaphore based implementation.
You can find a multithreaded queue implementation based on semaphores that I use here:
https://gist.github.com/482342
The reason for using semaphores is that you can avoid having the worker threads continually polling, and instead have them woken up by the OS when there is work to be done.