views:

987

answers:

2

Hi all,

I am reading data from multiple serial ports. At present I am using Custom signal handler (by setting sa_handler) to compare and wake threads based on file descriptor information. I was searching for a way out to have individual threads with unique signal handlers, in this regard I found that select system call is to be used. Now I have following questions:

  1. If I am using a thread (Qt) then where do I put the select system call to monitor the serial port?
  2. Is the select system call thread safe?
  3. Is it CPU intensive because there are many things happening in my app including GUI update?

Please do not mind, if you find these questions ridiculous. I have never used such a mechanism for serial communication. Also

A: 

It is a system call -- it should be thread save, I think.

I did not do this before, but I would be rather surprised, if it where not. How CPU intensive select is, depends in my opinion largely on the number of file handles you are waiting for. select is mostly used, to wait for a number (>1) of file handles to become ready.

It should also be mentioned that select should not be used to poll the file handles -- for performance reason. Normal usage is: You have your work done and some time can elapse till the next thing is going on. Now you suspend your process with select and let an other process run. Select normally does suspend the active process. How this works together with threads, I am not sure! I would think, that the whole process (and all threads) are suspended. But this might be documented. It also could depend (on Linux) whether you use system-threads or User-Threads. The kernel will not know User-Threads and hence suspend the whole process.

Juergen
+2  A: 

The POSIX specification (select) is the place to look for the select definition. I personally recommend poll - it has a better interface and can handle any number of descriptors, rather than a system-defined limit.

If I understand correctly you're waking threads based on the state of certain descriptors. A better way would be to have each thread have its own descriptor and call select itself. You see, select does not modify the system state, and as long as you use thread-local variables it'll be safe. However, you will definitely want to ensure you do not close a descriptor that a thread depends on.

Using select/poll with a timeout leaves the "waiting" up to the kernel side, which means the thread is usually put to sleep. While the thread is sleeping it is not using any CPU time. A while/for loop on a select call without a timeout on the other hand will give you a higher CPU usage as you're constantly spinning in the loop.

Hope this helps.

EDIT: Also, select/poll can have unpredictable results when working with the same descriptor in multiple threads. The simple reason for this is that the first thread might be woken up because the descriptor is ready for reading, but the second thread has to wait for the next "available for reading" wakeup.

As long as you're not selecting on the same descriptor in multiple threads you should not have a problem.

Matthew Iselin