In my understanding EPOLLEXCLUSIVE will only wake one thread per event, but if more events happen it will retrigger.
Suppose I'm reading from multiple sockets using multiple threads, all using epoll_wait, with EPOLLEXCLUSIVE.
Data comes on socket S ==> thread A wakes
More data comes on Socket S ==> thread B wakes
If #2 happens before A is finished, it could be the case that A and B are reading from the socket simultaneously?
Is my understanding correct?
Related
I am doing a task to receive user input in one thread (thread 1) and another thread(thread 2) to send cyclic CAN messages on a linux environment. The flow of the program is as follows,
In main thread, created a socket using socket(AF_INET,SOCK_STREAM,0) for server-client TCP connection
Bind was successfully done.
Using accept(), server-client established
Upon 3) , two threads are created, thread1 and thread2
thread 1 for user input from recv(), http://man7.org/linux/man-pages/man2/recv.2.html
thread 2 created socket for CAN communication using socket and uses timer to send the CAN messages with specified interval, continuously.
In thread2, I have used timer_create to send cyclic messages, which uses write function to write the CAN messages in the CAN socket.
http://man7.org/linux/man-pages/man2/timer_create.2.html
The problem is I have recv in an infinite loop in thread1 waiting for user input and the timer function in thread2 is also continuous. This makes recv to exit with signal interruption EINTR from thread1. I have tried the following,
Created a condition wait using pthread_cond_wait in thread 1, to wait for status update from thread 2. This does not work, as once the timer has started, it does not check for condition variable any more.
Does anyone has similar experience with using socket in two infinite loops for receiving and sending in two threads and controlling it on a condition variable. Any suggestion on how to handle them?
http://doc.qt.io/qt-5/threads-qobject.html#per-thread-event-loop
https://wiki.qt.io/Threads_Events_QObjects#Per-thread_event_loop
These two links talk about event loop. Please explain the "meaning" of the term "event loop" w.r.t threads in Qt?
An event loop is usually a loop that is run by the main thread to receive events that either originate from the system (e.g. GUI interaction, network events, timers, ...) or from other Qt components (e.g. QCoreApplication::postEvent(), ...). The event loop waits for new events to arrive in the event queue, then takes them out of the queue and sends them to their destination QObject where they are handled by an overridden QObject::event(QEvent*) (e.g. A QPushButton would handle a mouse press event by emitting pressed(), ...).
Per-thread event loops are a generalization of the concept above. This makes it possible to handle events in worker threads by introducing the concept of a QObject's thread affinity. Thread affinity is the thread in which a particular QObject should have its events handled (the thread from which QObject::event gets called for this QObject). In the big picture, this can be used to run asynchronous code in worker threads (since GUI code should be run only in the main thread). For example, you can run many asynchronous sockets and have QTimers to disconnect these sockets after some specified time of inactivity all in a single worker thread. Per-thread event loops are also essential for cross-thread signal-slot connections, since this kind of signal emissions is translated into QMetaCallEvents under the hood (to be delivered to its destination QObject).
I need to repeatedly send and receive UDP datagrams to/from a socket. My idea was to spawn two threads, one responsible for sending and the other for receiving. The whole idea makes sense only if it is possible to one thread to wait on a blocking recv() and the other executing send() on the same socket at the same time.
I did some Googling and found this SO question: Are parallel calls to send/recv on the same socket valid? The accepted answer mentions that send() and recv() are thread-safe (whew…), but then proceeds with an alarming remark:
This doesn't necessarily mean that they'll be executed in parallel
Oops. Does this mean that if I implement my multithreaded idea, will I end up with the sending thread waiting for the receiving thread’s recv() to return before it actually starts sending its data? Bad.
It is ambiguous whether this accepted answer refers to two parallel send()’s only, or if the concern is real also for an attempt to parallely execute one send() and one recv(). Therefore:
Will a call to send() and a call to recv() on the same socket by two threads be executed parallely, or will one of these calls block until the other returns?
Short answer: You should be ok to have separate threads for sending and receiving with the same socket handle.
A common scenario is a video conferencing application. You might want to have one thread recording from the microphone and sending audio out the udp port. Another thread receives packets on the same port and plays them back over the speakers.
If your protocol is more synchronous (i.e. request/response flow - in order to send, you first have to receive something first), then a single likely thread makes more sense from a design perspective.
What if multiple threads epoll wait on the same socket?
In my own experiment, it showed that only one thread can invoke epoll_wait successfully, the other threads show Invalid arguments error. Could someone explain it?
You can call epoll_wait concurrently on multiple threads for the same epoll_fd.
event.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
http://www.csh.rit.edu/~rossdylan/presentations/EpollMT/
You can epoll_wait concurrently on multiple threads for the same fd. But epoll doesn't handle thread synchronization like IOCP. It is possible that all the threads come out of epoll_wait call when an event occurs on one of the sockets. Usually only one thread is enough to wait on epoll_wait. You can then give the task of receiving or sending data to other threads from the epoll_wait thread (polling thread).
I have several threads, one of them calls epoll_wait in a loop, others can open connections that need to be epoll'ed by first thread. Is it possible to just add new sockets with epoll_ctl while another thread waits in epoll_wait?
What will happen in the following scenario:
Thread 1 calls epoll_wait.
Thread 2 creates a socket(A) and adds it to epoll instance using epoll_ctl.
Someone sends some data, socket A becomes ready for read() call.
Will epoll_wait return socket A?
Yes, it will. The whole point of an epoll socket is that you don't have to duplicate effort. No snapshotting or use of multiple wait queues is involved.
Under the hood, the epoll socket has its own wait queue. When you block on the epoll socket, you are added to that single wait queue. No state is saved or anything like that. The state is in the epoll socket itself.