how to synchronize a varied number of threads? - c++

Could someone please help me with synchronizing varied number of threads? The problem is when the number of threads can vary from one to 9 and when for instance two clients are connected to server, the communication should be synchronized in this form : client1, client2, client1, client2 ... until the communication is over.
I tried with pthread_join , pthread_mutex_lock and pthread_mutex_lock, but this blocks client1 until finish communicating to start client2.
Any help would be appreciated and thanks for your reply

I actually don't understand well how the threads should be synchronized. If there is some block of code that needs to be done in a serialized manner then the pthread_mutex_lock should be good enough. If the order of operation should be preserved (1,2,3,1,2,3) I suggest using pthread_mutex_lock along with some variable indicating which thread is allowed to enter the critical section now.
// id_to_go iterates from 0 up to number_of_thread - 1
// each thread has my_id from the same range
while(1)
{
pthread_mutex_lock(mutex);
if (id_to_go == my_id)
{
// set to next thread id
id_to_go = (id_to_go + 1) % number_of_threads;
}
else
{
// it's not our turn, try again
pthread_mutex_unlock(mutex);
continue;
}
handle_the_client;
pthread_mutex_unlock(mutex);
}

The solution is to release the lock after you've sent a message, then take it again when you want to send another one.

Related

Multithreading Implementation in C++

I am a beginner using multithreading in C++, so I'd appreciate it if you can give me some recommendations.
I have a function which receives the previous frame and current frame from a video stream (let's call this function, readFrames()). The task of that function is to compute Motion Estimation.
The idea when calling readFrames() would be:
Store the previous and current frame in a buffer.
I want to compute the value of Motion between each pair of frames from the buffer but without blocking the function readFrames(), because more frames can be received while computing that value. I suppose I have to write a function computeMotionValue() and every time I want to execute it, create a new thread and launch it. This function should return some float motionValue.
Every time the motionValue returned by any thread is over a threshold, I want to +1 a common int variable, let's call it nValidMotion.
My problem is that I don't know how to "synchronize" the threads when accessing motionValue and nValidMotion.
Can you please explain to me in some pseudocode how can I do that?
and every time I want to execute it, create a new thread and launch it
That's usually a bad idea. Threads are usually fairly heavy-weight, and spawning one is usually slower than just passing a message to an existing thread pool.
Anyway, if you fall behind, you'll end up with more threads than processor cores and then you'll fall even further behind due to context-switching overhead and memory pressure. Eventually creating a new thread will fail.
My problem is that I don't know how to "synchronize" the threads when accessing motionValue and nValidMotion.
Synchronization of access to a shared resource is usually handled with std::mutex (mutex means "mutual exclusion", because only one thread can hold the lock at once).
If you need to wait for another thread to do something, use std::condition_variable to wait/signal. You're waiting-for/signalling a change in state of some shared resource, so you need a mutex for that as well.
The usual recommendation for this kind of processing is to have at most one thread per available core, all serving a thread pool. A thread pool has a work queue (protected by a mutex, and with the empty->non-empty transition signalled by a condvar).
For combining the results, you could have a global counter protected by a mutex (but this is relatively heavy-weight for a single integer), or you could just have each task added to added to the thread pool return a bool via the promise/future mechanism, or you could just make your counter atomic.
Here is a sample pseudo code you may use:
// Following thread awaits notification from worker threads, detecting motion
nValidMotion_woker_Thread()
{
while(true) { message_recieve(msg_q); ++nValidMotion; }
}
// Worker thread, computing motion on 2 frames; if motion detected, notify uysing message Q to nValidMotion_woker_Thread
WorkerThread(frame1 ,frame2)
{
x = computeMotionValue(frame1 ,frame2);
if x > THRESHOLD
msg_q.send();
}
// main thread
main_thread()
{
// 1. create new message Q for inter-thread communication
msg_q = new msg_q();
// start listening thread
Thread a = new nValidMotion_woker_Thread();
a.start();
while(true)
{
// collect 2 frames
frame1 = readFrames();
frame2 = readFrames();
// start workre thread
Thread b = new WorkerThread(frame1 ,frame2);
b.start();
}
}

Multiple client and single server handling

Will this approach work?
I am gonna simply present my code in simplified form for easier readability.
I am trying to implement a multiple client/one TCP server.
My listener will loop like this(as a thread) which handles connections
void WaitAndAcceptConnection(){
if(socket_TEMP = accept(sock_LISTEN, (SOCKADDR*)&ADDRESS, &AddressSize))
{
socketsManager.push_back(socket_TEMP);
currCount++;
std::cout<<"\n A connection was found!"<<std::endl;
send(socketsManager[currCount], "Welcome! you have connected to Athena Server", 46,NULL);
// cond.notify_one(); //notify the waiting thread
}
}
wherein i have..
std::vector<SOCKET> socketsManager; //handles socket
int currCount=-1; //keep track on the number of connections
If a client connected then currCount will be increased by one, in our case it's gonna be currCount = 0 and then socketsManager[0] will store the accept's return. If another one connected then currCount = 1 then socketsManager[1] will be its handler.
For sending and receiving data.
I am gonna make a for loop that will continue on iterating to check if there is a recv'd data(-1 or 0) for every sockets that is being handled by my program.
void WaitAndAcceptCommands(){
for(int i = 0; i<= currCount;i++){
int result = recv(socketsManager[i],&command,1,0);
if(result ==-1){
}
else if(result == 0){
}
else{
//process commands
}
}
}
Main will be something like this
Athena ath2; //instance of the server
std::cout<<"\n >Waiting for incoming connections..."<<std::endl;
//listener thread, just keep on LOOPING
std::thread connectionThread([&](){
while(1){
ath2.WaitAndAcceptConnection();
}
});
//handles all the inputs, JUST KEEP ON LOOPING
std::thread commandsThread([&](){
while(1){
ath2.WaitAndAcceptCommands();
}
});
connectionThread.join(); //stop
commandsThread.join(); //stop
I would gladly show the rest of my code but they are in a complete mess right now. I only wanted to present the idea if this will work and then i will continue on it, if not then i will reconsider another method. I plan on handling my connections through timeouts if i will ever have to drop a socket from my std::vector<SOCKET> socketsManager; by using remove. Is this a good method? if not then what are the issues?
I see a couple of problems with what you're doing:
You're pushing to socketsManager vector indefinitely. It won't be long before you run out of memory / file descriptors.
Protect access to socketsManager with some lock, else you can have race condition.
One way to do this is to use event loop:
Have one or more threads for doing I/O.
Each I/O thread operates on a list of open sockets.
It uses select() or poll() to figure out which socket amongst the set it is operating on has data available. Invokes the necessary callbacks with the data that was read.
Processing the data is handled by worker threads. The callback invoked one of the worker thread which processes the data.
References:
http://instagram-engineering.tumblr.com/post/121930298932/c-futures-at-instagram (see non-blocking IO section)

How can I use Boost condition variables in producer-consumer scenario?

EDIT: below
I have one thread responsible for streaming data from a device in buffers. In addition, I have N threads doing some processing on that data. In my setup, I would like the streamer thread to fetch data from the device, and wait until the N threads are done with the processing before fetching new data or a timeout is reached. The N threads should wait until new data has been fetched before continuing to process. I believe that this framework should work if I don't want the N threads to repeat processing on a buffer and if I want all buffers to be processed without skipping any.
After careful reading, I found that condition variables is what I needed. I have followed tutorials and other stack overflow questions, and this is what I have:
global variables:
boost::condition_variable cond;
boost::mutex mut;
member variables:
std::vector<double> buffer
std::vector<bool> data_ready // Size equal to number of threads
data receiver loop (1 thread runs this):
while (!gotExitSignal())
{
{
boost::unique_lock<boost::mutex> ll(mut);
while(any(data_ready))
cond.wait(ll);
}
receive_data(buffer);
{
boost::lock_guard<boost::mutex> ll(mut);
set_true(data_ready);
}
cond.notify_all();
}
data processing loop (N threads run this)
while (!gotExitSignal())
{
{
boost::unique_lock<boost::mutex> ll(mut);
while(!data_ready[thread_id])
cond.wait(ll);
}
process_data(buffer);
{
boost::lock_guard<boost::mutex> ll(mut);
data_ready[thread_id] = false;
}
cond.notify_all();
}
These two loops are in their own member functions of the same class. The variable buffer is a member variable, so it can be shared across threads.
The receiver thread will be launched first. The data_ready variable is a vector of bools of size N. data_ready[i] is true if data is ready to be processed and false if the thread has already processed data. The function any(data_ready) outputs true if any of the elements of data_ready is true, and false otherwise. The set_true(data_ready) function sets all of the elements of data_ready to true. The receiver thread will check if any processing thread still is processing. If not, it will fetch data, set the data_ready flags, notify the threads, and continue with the loop which will stop at the beginning until processing is done. The processing threads will check their respective data_ready flag to be true. Once it is true, the processing thread will do some computations, set its respective data_ready flag to 0, and continue with the loop.
If I only have one processing thread, the program runs fine. Once I add more threads, I'm getting into issues where the output of the processing is garbage. In addition, the order of the processing threads matters for some reason; in other words, the LAST thread I launch will output correct data whereas the previous threads will output garbage, no matter what the input parameters are for the processing (assuming valid parameters). I don't know if the problem is due to my threading code or if there is something wrong with my device or data processing setup. I try using couts at the processing and receiving steps, and with N processing threads, I see the output as it should:
receive data
process 1
process 2
...
process N
receive data
process 1
process 2
...
Is the usage of the condition variables correct? What could be the problem?
EDIT: I followed fork's suggestions and changed the code to:
data receiver loop (1 thread runs this):
while (!gotExitSignal())
{
if(!any(data_ready))
{
receive_data(buffer);
boost::lock_guard<boost::mutex> ll(mut);
set_true(data_ready);
cond.notify_all();
}
}
data processing loop (N threads run this)
while (!gotExitSignal())
{
// boost::unique_lock<boost::mutex> ll(mut);
boost::mutex::scoped_lock ll(mut);
cond.wait(ll);
process_data(buffer);
data_ready[thread_id] = false;
}
It works somewhat better. Am I using the correct locks?
I did not read your whole story but if i look at the code quickly i see that you use conditions wrong.
A condition is like a state, once you set a thread in a waiting condition it gives away the cpu. So your thread will effectively stop running untill some other process/thread notifies it.
In your code you have a while loop and each time you check for data you wait. That is wrong, it should be an if instead of a while. But then again it should not be there. The checking for data should be done somewhere else. And your worker thread should put itself in waiting condition after it has done its work.
Your worker threads are the consumers. And the producers are the ones that deliver the data.
I think a better construction would be to make a thread check if there is data and notify the worker(s).
PSEUDO CODE:
//producer
while (true) {
1. lock mutex
2. is data available
3. unlock mutex
if (dataAvailableVariable) {
4. notify a worker
5. set waiting condition
}
}
//consumer
while (true) {
1. lock mutex
2. do some work
3. unlock mutex
4. notify producer that work is done
5. set wait condition
}
You should also take care of the fact that some thread needs to be alive in order to avoid a deadlock, means all threads in waiting condition.
I hope that helps you a little.

c++ Handling multiple threads in a main thread

I am a bit new to multi threading, so forgive me if these questions are too trivial.
My application needs to create multiple threads in a thread and perform actions from each thread.
For example, I have a set of files to read, say 50 and I create a thread to read these files using CreateThread() function.
Now this main thread creates 4 threads to access the file. 1st thread is given file 1, second file 2 and so on.
After 1st thread completed reading file 1 and gives main thread the required data, main thread needs to invoke it with file 5 and obtain data from it. Similar goes for all other threads until all 50 files are read.
After that, each thread is destroyed and finally my main thread is destroyed.
The issue I am facing is:
1) How to stop a thread to exit after file reading?
2) How to invoke the thread again with other file name?
3) How would my child thread give information to main thread?
4) After a thread completes reading the file and returns the main thread a data, how main thread would know which thread has provided the data?
Thanks
This is a very common problem in multi-threaded programming. You can view this as a producer-consumer problem: the main thread "produces" tasks which are "consumed" by the worker threads (s. e.g. http://www.mario-konrad.ch/blog/programming/multithread/tutorial-06.html) . You might also want to read about "thread pools".
I would highly recommend to read into boost's Synchronization (http://www.boost.org/doc/libs/1_50_0/doc/html/thread.html) and use boost's threading functionality as it is platform independent and good to use.
To be more specific to your question: You should create a queue with operations to be done (usually it's the same queue for all worker threads. If you really want to ensure thread 1 is performing task 1, 5, 9 ... you might want to have one queue per worker thread). Access to this queue must be synchronized by a mutex, waiting threads can be notified by condition_variables when new data is added to the mutex.
1.) don't exit the thread function but wait until a condition is fired and then restart using a while ([exit condition not true]) loop
2.) see 1.
3.) through any variable to which both have access and which is secured by a mutex (e.g. a result queue)
4.) by adding this information as the result written to the result queue.
Another advice: It's always hard to get multi-threading correct. So try to be as careful as possible and write tests to detect deadlocks and race conditions.
The typical solution for this kind of problem is using a thread pool and a queue. The main thread pushes all files/filenames to a queue, then starts a thread pool, ie different threads, in which each thread takes an item from the queue and processes it. When one item is processed, it goes on to the next one (if by then the queue is not yet empty). The main thread knows everything is processed when the queue is empty and all threads have exited.
So, 1) and 2) are somewhat conflicting: you don't stop the thread and invoke it again, it just keeps running as long as it finds items on the queue.
For 3) you can again use a queue in which the thread puts information, and from which the main thread reads. For 4) you could give each thread an id and put that together with the data. However normally the main thread should not need to know which thread exactly processed data.
Some very basic pseudocode to give you an idea, locking for threadsafety omitted:
//main
for( all filenames )
queue.push_back( filename );
//start some thread
threadPool.StartThreads( 4, CreateThread( queue ) );
//wait for threads to end
threadPool.Join();
//thread
class Thread
{
public:
Thread( queue q ) : q( q ) {}
void Start();
bool Join();
void ThreadFun()
{
auto nextQueueItem = q.pop_back();
if( !nextQueuItem )
return; //q empty
ProcessItem( nextQueueItem );
}
}
Whether you use a thread pool or not to execute your synchronies file reads, it boils down to a chain of functions or groups of functions that have to run serialized. So let's assume, you find a way to execute functions in parallel (be it be starting one thread per function or by using a thread pool), to wait for the first 4 files to read, you can use a queue, where the reading threads push there results into, the fifth function now pulls 4 results out of the queue (the queue blocks when empty) and processes. If there are more dependencies between functions, you can add more queues between them. Sketch:
void read_file( const std::string& name, queue& q )
{
file_content f= .... // read file
q.push( f )
}
void process4files( queue& q )
{
std::vector< file_content > result;
for ( int i = 0; i != 4; ++i )
result.push_back( q.pop() );
// now 4 files are read ...
assert( result.size() == 4u );
}
queue q;
thread t1( &read_file, "file1", q );
thread t2( &read_file, "file2", q );
thread t3( &read_file, "file3", q );
thread t4( &read_file, "file4", q );
thread t5( &process4files, q );
t5.join();
I hope you get the idea.
Torsten

Stop and start running again processes in Linux using C++

I have two process and a shared memory zone, my workflow is like this. The process A write some data in the shared memory, after that it should wait and send a signal to other process B to start running. The process B should read some data from the shared memory do some stuff write the result, and send a signal to the process A to keep running, after this process B should wait.
Can anyone plese provide an example or a place where I can find how can I stop a process and how can I start running again the process?. I am working in Linux and C++.
I already have semaphores, but the thing that I do not like, it is that one process is stop a bunch of seconds reading all the time from the shared memory, until it detects that it can run. That's why I was thinkin only in send a signal in the right moment
Update with the solution
I selected the answer of stefan.ciobaca as favourite because is a complete solution that it works and it has a very good explanation. But in all of the other answers there are other interesting options.
Here is a proof-of-concept of how it can be done:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <assert.h>
typedef void (*sighandler_t)(int);
#define SHM_SIZE 8 /* size of shared memory: enough for two 32 bit integers */
volatile int cancontinue = 0;
void halt(char *err) { perror(err); exit(1); }
void handler(int signum) { assert(signum == SIGUSR1); cancontinue = 1; }
int main(void)
{
key_t key;
int id;
int *data;
pid_t otherpid;
printf("Hi, I am the %s process and my pid is %d\n",
#ifdef PRODUCER_MODE
"writer"
#else
"reader"
#endif
, getpid());
printf("Please give me the pid of the other process: ");
scanf("%d", &otherpid);
// get a pointer to the shared memory
if ((key = ftok("test_concur.c", 'R')) == -1) halt("ftok");
if ((id = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) halt("shmget");
if ((data = shmat(id, (void *)0, 0)) == (int *)(-1)) halt("shmat");
sighandler_t oldhandler = signal(SIGUSR1, handler);
while (1) {
#ifdef PRODUCER_MODE
printf("Enter two integers: ");
scanf("%d %d", data, data + 1);
printf("Sending signal to consumer process\n");
kill(otherpid, SIGUSR1);
printf("Waiting for consumer to allow me to continue\n");
while (!cancontinue);
cancontinue = 0;
if (*data + *(data + 1) == 0) { printf("Sum was 0, exiting...\n"); break; }
#else
printf("Waiting for producer to signal me to do my work\n");
while (!cancontinue);
cancontinue = 0;
printf("Received signal\n");
printf("Pretending to do a long calculation\n");
sleep(1);
int sum = *data + *(data + 1);
printf("The sum of the ints in the shared memory is %d\n", sum);
printf("Signaling producer I'm done\n");
kill(otherpid, SIGUSR1);
if (sum == 0) break;
#endif
}
signal(SIGUSR1, oldhandler);
/* detach from the segment: */
if (shmdt(data) == -1) {
perror("shmdt");
exit(1);
}
// don't forget to remove the shared segment from the command line with
// #sudo ipcs
// ... and look for the key of the shared memory segment
// #ipcrm -m <key>
return 0;
}
The above program is actually two programs, a consumer and a producer,
depending on how you compile it.
You compile the producer by making sure that the PRODUCER_MODE macro
is defined:
# gcc -Wall -DPRODUCER_MODE -o producer test_concur.c
The consumer is compiled without defining the PRODUCER_MODE macro:
# gcc -Wall -o consumer test_concur.c
The consumer and producer share some global memory (8 bytes pointed to by data); the producer's role is to read two 32-bit integers from stdin and write them to the shared
memory. The consumer reads integers from the shared memory and
computes their sum.
After writing the data to shared memory, the producer signals to the
consumer (via SIGUSR1) that it may begin the computation. After the
computation is done, the consumer signals to the producer (via SIGUSR1
again) that it may continue.
Both processes stop when the sum is 0.
Currently, each program begins by outputing its pid and reading from
stdin the other program's pid. This should probably :D be replaced by
something smarter, depending on exactly what you are doing.
Also, in practice, the "while (!cancontinue);"-like loops should be
replaced by something else :D, like semaphores. At least you should do
a small sleep inside each loop. Also, I think you do not truly need shared memory to solve this problem, it should be doable using message-passing techniques.
Here is an example session, showed in parallel:
# ./producer # ./consumer
Hi, I am the writer process and my pid is 11357 Hi, I am the reader process and my pid is 11358
Please give me the pid of the other process: 11358 Please give me the pid of the other process: 11357
Enter two integers: 2 Waiting for producer to signal me to do my work
3
Sending signal to consumer process Received signal
Waiting for consumer to allow me to continue Pretending to do a long calculation
... some times passes ...
The sum of the ints in the shared memory is 5
Signaling producer I'm done
Enter two integers: 0 Waiting for producer to signal me to do my work
0
Sending signal to consumer process Received signal
Waiting for consumer to allow me to continue Pretending to do a long calculation
... some times passes ...
The sum of the ints in the shared memory is 0
Signaling producer I'm done
Sum was 0, exiting...
I hope this helps. (when you run the programs, make sure the file test_concur.c exists (it's used to establish the shared memory key (ftok function call)))
Not quite what you've asked for, but could you use pipes (named or otherwise) to affect the synchronization? This puts the locking burden onto the OS which already knows how to do it.
Just a thought.
Response to comment: What I had in mind was using pipes rather than shared memory to more the data around, and getting synchronization for free.
For instance:
Process A starts, sets up a bi-directional pipe and forks process B using popen (3).
Immediately after the fork:
A does some work and writes to the pipe
B attempts to read the pipe, which will block until process A writes...
Next:
A attempts to read the pipe, which will block until data is available...
B does some work and writes to the pipe
goto step 2 until you reach a ending condition.
This is not what you asked for. No shared memory, no signals, but it should do the trick...
What about using Unix domain sockets for the IPC instead of shared memory? That way each process can block on reading from the socket while the other does its work.
Edit: This is similar to dmckee's answer, but offers more control on the blocking and IPC. The popen approach is definitely easier to implement, however.
Do you really need to stop the process (exit it), and restart it, or do you just want it to wait until some event occurs?
If the latter you should read up on IPC and process synchronisation (e.g. semaphores, mutexes).
If the former, look at the source code for something like init in linux.
What you are looking for is called blocking. Process B should block on a call from process A and Process A should block on a call from process B. If a processes is blocked (waiting for the call from the other process) it sits idly in the background and only wakes up when it receives a message.
Select is probably the function you are looking for.
I suggest using semaphores to synchronize the processes.
Reading the headline, I thought that SIGSTOP and SIGCONT might be possibilities, but that's probably not a good idea; you want them to stop when they're in the right (safe) place to stop. That's what semaphores are for.
Many other IPC mechanisms could also achieve similar results, but semaphores are cross-process communication mechanisms (you'd use mutexes between different threads in a single process).
You may also want to look into boost message queues which will use shared memory under the hood, but hides all the hard parts. It offers both blocking and non-blocking functions (it sounds like you want blocking).