I am trying to do concurrent reads and writes in a C++ program to a file descriptor that connects to a UART device. What I am doing is similar to the following pseudocode
fd = get_fd();
make_non_blocking(fd);
while (1) {
check_to_see_if_there_are_writes_pending_and_do_them();
read_all_available_data_and_signal_waiting_threads();
}
The way a thread writes to this file descriptor is by writing its data block to a queue and then the check_to_see_if_there_are_writes_pending_and_do_them()
function polls that queue and makes the writes. But as you guys can probably notice, there is busy waiting here. Is there a way that I can somehow make maybe a select()
or poll()
call that releases a mutex and then sleeps until there is data and then as soon as there is data it acquires the mutex again and then reads from the file descriptor? I can just add the select()
call before the read_all_available_data_and_signal_waiting_threads()
function call but I do not know whether calling select()
or poll()
on a file descriptor that is being written to will cause problems. I am talking about code like the following
fd = get_fd();
make_non_blocking(fd);
while (1) {
check_to_see_if_there_are_writes_pending_and_do_them();
release_mutex_so_writer_threads_can_access();
select(fd);
acquire_mutex();
read(fd);
}
Could someone please show me an acceptable way to achieve this? Or whether the above method is fine and the OS (a Mac OSx version 10.11.3) takes care of the multiplexing and the thread safety for me?
Thanks!
NOTE : I read a question that seems to be related to this question elsewhere on Stack Overflow but I do not believe that I have the same problem here. If I am wrong please link me to it and I will delete this question!
NOTE : I am currently using condition variables to build the thread safe write queue. I wanted to ask whether it would be okay to interleave a select()
or poll()
call with a write()
to the same fd.