modifying a struct with multiple threads c programming - c

I have been all over the internet with no one directly answering this question. So I have a struct in my main process and I need multiple threads to modify it. I know that I am going to need mutexs to protect the data, but is there any way to share pointers with out passing it as an arg in pthread_create. I understand that threads share the same memory address and there for if I allocate in one the other should have access to it. But with out passing a pointer how do the threads know that a certain pointer already exists.

The typical answer to your question is that rather than passing the pointer directly to the thread when you call pthread_create, you instead pass a pointer to some higher-level structure that serves as your communication with the thread.
For example, say you are writing a network server that receives requests from clients and then needs to process those requests. The threads that process requests from clients would typically be passed the address of some kind of waitable queue. When a thread receives a request from a client, it would put that request in the waitable queue. The threads that process client requests are already waiting for things to be put on that queue, and they get the information about the request they need to process from the queue.

Related

Posix select()/poll() and pthread IPC

This is kind of generic question - however I met this problem several times already and I still haven't found the best possible solution.
Let's imagine you have program (e.g. HTTP application server) that is multithreaded and that communicates over sockets (TCP, Unix, ...). Main thread is using asynchronous IO and select() or poll() POSIX calls to dispatch traffic from/to sockets. There are also worker threads that process requests and provides responses. To send response back to the client, worker thread synchronises with main thread (that polls) 'somehow'. Core of the questions is 'how' - in terms of what is efficient. I can use pipe() - socket based IPC mechanism - but this seems to me as quite huge overhead. I tend to use some pthread IPC techniques like mutex, condition variables etc. … but these will not work with select() or poll().
Is there a common technique in POSIX (and surroundings) that address this conflict?
I guess on Windows there is WaitForMultipleObjects() function that allows that.
Example program is crafted to illustrate an issue, I know that I can design master/worker pattern in a different way but this is not what I'm asking for. I have other cases where I'm in the same situation.
You could use a signal to poke the worker thread, which will interrupt the select() call and return EINTR. This gets even easier to do with pselect().
For this to work:
decide on a signal (or allocate a real-time signal)
attach an empty handler function to it (if the signal were ignored, the system call would be automatically restarted)
block the signal, at least in the worker thread.
use the signal mask argument in pselect() to unblock the signal while waiting.
Between threads, you can use pthread_kill to deliver the signal to the worker thread specifically. When another process should send the signal, you can either make sure the signal is blocked in all but the worker thread (so it will be delivered there), or use the signal handler to find out whether the signal was sent to the worker thread, and use pthread_kill to forward it explicitly (the worker thread still doesn't need to do anything in the signal handler).
Due to laziness on my part, I don't have a source code viewer online, but you can clone the LibreVISA git tree, and take a look at src/messagepump.cpp, where this method is used to poke the worker thread after another thread added a file descriptor to the watch list.
Simon Richthers answer is v good.
Another alternative might be to make main thread only responsible for listening for new connections and starting up a worker thread with the connection information so that the worker is responsible for all subsequent ‘transactions’ from this source.
My understanding is:
Main thread uses select.
Worker threads processes requests forwarded to it by main thread.
So need to synchronize between workers and main thread e.g. when
worker finishes a transaction need to send response back to main
thread which in turn forwards the response back to the source.
Why don't you remove the problem of having to synchronize between the worker thread and the main thread by making the worker thread responsible for all transactions from a particular connection?
Thus the main thread is only responsible for listening for new connections and starting up a worker thread with the connection information i.e. the file descriptor for the new connection.
First of all, the way to wake another thread is to use the pthread_cond_wait / pthread_cond_timedwait calls in thread A to wait, and for thread B to use pthread_cond_broadcast / pthread_cond_signal to pick it up. So, for instance if B is a producer and A is the consumer, the producer might add items to a linked list protected with a mutex. There would be an associated conditional variable such that after the addition of the item, it could wake thread B such that it went to see if any new items had arrived on the list, and if so removed them. I say 'associated' as then the same mutex can be associated with the condition variable as protects the list.
So far so good. Now you mention asynchronous I/O. What I've wanted to do several times is select() or poll() on a set of FDs and a set of condition variables, so the select(), poll() is interrupted when the condition variable is broadcasted to. There is no easy way of doing this directly; you cannot simply mix and match.
You thus need to do one of two things. Either:
work around the problem (for instance, use a self-connected pipe() to send one byte to wake the select() up either instead of the condition variable, as well as the condition variable, or from some additional thread waiting on the condition variable; or
convert to a more threaded model. IE use one thread for sending, one thread for receiving, and use a producer / consumer model, so the sender thread simply removes from a list / buffer and sends (blocking if necessary), and the received waits for I/O (blocking if necessary) and adds it to the list (this is what you put in italics at the end).
The second is a major design change for those of us brought up on asynchronous I/O, and the first is ugly. You are not the first to be dismayed by this, but I've not found an easy way around it. Re the first an inefficiency, if you only write one character to wake the select loop to the self-pipe, I don't think you are going to see too much inefficiency.

Multithreaded udp server

I'm new with threads and please if you can advice me. I have server that broadcast messages
to clients. Then clients sends back replies to server. I want to handle every reply using
seperate thread. Every reply will have mesage id and thread id. How can I fill some structure
with this information from all threads and then read it
Also from my code, is it correctly to create thread in while or does it exist someway
to create thread just if I get reply from client?
Did I start with correct understanding?
int main(){
while(1){
sendto on broadcast IP
pthread_create(&cln_thread, NULL, msg_processing, (void *) &arg))
}
}
msg_processing () {
recvfrom client msg with id of packet and thread id
how to write those informations and then read them in main when program finish
}
Thank you
Err.. no, just create ONE thread, once only, for receiving datagrams on one socket. In the thread function, receive the datagrams in a while(true) loop. Don't let this receive thread terminate and don't create any more receive threads. Continually creating/terminating/destroying threads is inefficient, dangerous, unnecessary, error-prone, difficult-to-debug and you should try very hard to not do it, ever.
Edit:
One receive thread only - but you don't have to do the processing there. Malloc a 64K buffer, receive data into it, push the buffer pointer onto a producer-consumer queue to a pool of threads that will do the processing, loop back and so malloc again to reseat the pointer and create another buffer for the next datagram. Free the *buffers in the pool threads after the processing is completed. The receive thread will be back waiting for datagrams quickly while the buffer processing runs concurrently.
If you find that the datagrams can arrive so rapidly that the processing cannot keep up, memory use will grow unchecked as more and more *buffers pile up in the queue. There are a couple ways round that. You can use a bounded queue that blocks if its capacity is reached. You could create x buffers at startup and store them on another producer-consumer 'pool queue' that the receive thread pops from, (instead of the malloc) - the processing pool threads can then push the 'used' *buffers back on to the pool queue for re-use. If the pool runs out, the receive thread will block on the pool until *buffers are returned.
I prefer the pooled-buffer approach since it caps memory-use across the whole system, avoids continual malloc/free with its fragmentation issues etc, avoids the more complex bounded queues, is easier to tweak, (the pool level is easy to change at runtime), and is easier to monitor/debug - I usually dump the pool level, (ie. queue count), to the display once a second with a timer.
In either case, datagrams may be lost but, if your system is overloaded such that data regularly arrives faster than it can possibly be processed, that's going to be the case anyway no matter how you design it.
One socket is fine, so why complicate matters? :)
You can find a good example of a multithreaded UDP server in Go lang following:
https://gist.github.com/jtblin/18df559cf14438223f93
The main idea is to use multi-core functionality in a full so each thread works on its own CPU core and reads UDP data into the single buffer for processing.

How to send a variable/information between threads

I need to know how a thread can send its ID to another thread before it goes to wait state. I thought to pass a variable with its ID but I don't know how to do it.
If it's only one thread and its parent, you could use a global variable, as they are shared between all threads. Make it volatile in case you expect concurrent access.
EDIT: I'm not sure if you're using POSIX threads on Linux but you probably have a way to pass a pointer (e.g. to a struct) when creating the thread. It could contain a variable to store its ID or a pointer to a function to call on the parent thread. I know you can do it with Windows threads.
You can create a pointer in the thread which is pointing to the function in the parent (by reference). By the time it goes to wait state then it can just use that pointer to trigger something to its parent.
Threads share memory, so you can allocate a global variable and let the child write on it.
Than for the synchronization (aka inform the parent that a value has been written) you have many choices: you can use a semaphore, can send a signal from the thread back to its parent, use a synchronization variable like explained here.

share a struct throughout multiple thread

i am writing a small IRC program in C.I'm using thread to handle multiple clients,
and i use a chained list to store the fd of each client.So if a client send a message, it will be written on the fd of the others.
I'm not sure this is the best way to do, could you give me some advice ???
Plus, in this way, i need to share the struct (that contains the file descriptior of each clients) throughout the thread, so if there is an update in a thread, it will update the struc for the others.I'm wondering how i could do this, how could i share that struct ??
Any help is welcome.
Without knowing more about your design it's very difficult to comment on whether your linked list of FDs is appropriate.
In terms of sharing a struct of data between threads there is nothing you need to do. Threads share memory space so anything visible in one thread will be visible in another. Your only risk is that you have multiple threads modifying the struct at one time, something you protect against by using a mutex (mutual exclusion semaphore).
Since you're on Linux I'm assuming you're using POSIX Threads (pthreads) in which case you'll need to look at the pthread_mutex_ functions.
In your setup, I would use:
one input queue per channel,
one output queue per client.
Whenever a client thread receives a message, it posts it to the channel thread. When a channel receives a new post, it reposts it to all the clients. Each channel and client can be represented as a struct, which may be handled then by the threads (with one or more clients or channel per thread).
All queues are simple linked lists protected using a pthread_mutex_t. When a function needs to access them, it locks the queue, add the message, and unlock.
pthread_mutex_create
pthread_mutex_lock
pthread_mutex_unlock

Proper way to handle pthread communication / signals in this instance?

I'm writing a small client / server demo that shares files between peers. One a peer gets a list of ip addresses from the main server, the main thread creates a thread for each respective file. The process looks like this:
Main thread gets list of files from server
Thread created for each file (detached)
In each created thread, connect to the peers specified / associated with a file
Thread downloads the file in chunks
Thread announces the file was complete
My problem comes into play when trying to "query" a thread. In each thread, I keep track of the progress of a transfer. In my main thread, I would like the user to be able to see the progress of all of the transfers taking place. What would be the best way to do so? I was thinking about sending a signal using pthread_kill to each thread respectively, although it seems like there should be a better way. If anyone has an idea, I'd love to hear it.
When you create your thread, you include a void * to point to anything you wish. In your example, you could declare an array of progress values and pass the address of one of them to each thread you create, let the thread perform a simple update when it needs to, and your main thread can periodically check the values.
If you're already using that parameter for something, you will need to create a structure comprising this new value and whatever you're already using, and pass the address of it so the thread gets everything it needs.

Resources