Vadim Zeitlin wrote:
> I thought you were reading from a socket as file IO is usually fast
> enough
I am reading actually from a serial port. So
while I am using a file IO, it is not very fast.
The response time is not ultimately critical,
but still, for the non-blocking IO it may be
a noticeable overhead.
> SS> Also, your missing comment on the Thread.interrupt()
> No because I have no idea how do you propose to implement it.
I think something like siginterrupt() with pthread_kill()
(haven't really tried, sorry, but should be trivial).
> SS> And what exactly makes wxThread::Delete() to be blockable?
> Because it has to wait for the thread to exit, what do you mean?
I mean, AFAICS, it does so only for the joinable threads,
while for the detached ones, it probably never blocks.
Why it have to wait, if I would explicitly use wxThread::Wait()
anyway? And if wxThread::Delete() is already coded that way,
then maybe some other method is needed, which will only do
wxThreadInternal::SetCancelFlag() and nothing more?
Eran Ifrah wrote:
> On Unix like systems, use SIGALRM, but make sure the correct thread captures
> it.
Yes, that's a unix-specific solution, but I am also
concerned about Win32 a bit. That's why I was wondering
about the Thread.interrupt()-alike functionality in wx.
Why would wx lack something that even the Java has? :)
> Assuming you have Main thread, which creates reader thread.
> Now, when the Main thread wants to notify the reader thread to abort and
> exit, it simply closes the flie descriptor of the reader thread - this will
> cause the reader thread to return immediatly with return code
This solution is only partially portable AFAIK. To the
best of my knowledge, it doesn't work on Linux, where the
one thread can close an fd, and the other threads will
still be able to use it.
> (Make sure that the file descriptor it is a global or member of a singleton
> or whatever ... )
Hmm, just wondering, why does that matter?
> This solution worked for me fine for UNIX and Windows.
But have you tried it on linux? I haven't tried that since
they switched to the new threading model (NPTL or whatever
it is called). If it works these days - fine, I'll use that.
But I know it didn't work in the past, I even googled the
proof:
http://gcc.gnu.org/ml/java/2001-09/msg00108.html
(it also says the Java is not always very successfull with
this - uh-oh...)
Now I can probably use SIGALRM on linux and fd-closing on
everything else... but I just wanted wx to at least match
the functionality of Java in that area. I only need 2
small things: wxThread::Interrupt() and non-blocking wxThread::Delete()
to have it completely portable. But instead I am forced to
use the OS-specific tricks, oh well.
SS> Vadim Zeitlin wrote:
SS> > I thought you were reading from a socket as file IO is usually fast
SS> > enough
SS> I am reading actually from a serial port. So
SS> while I am using a file IO, it is not very fast.
I see. Hasn't there been a serial communications library announced here
some time ago? Maybe it has read with timeout?
SS> > SS> Also, your missing comment on the Thread.interrupt()
SS> > No because I have no idea how do you propose to implement it.
SS> I think something like siginterrupt() with pthread_kill()
SS> (haven't really tried, sorry, but should be trivial).
Yes, of course -- with pthreads. I was speaking about portable solutions.
Also, to deal with the Java argument once and for all: Java threads are not
OS threads to the best of my knowledge but just JVM abstraction and so they
could design any threading behaviour they wanted. We're constrained by the
existing implementation.
SS> > SS> And what exactly makes wxThread::Delete() to be blockable?
SS> > Because it has to wait for the thread to exit, what do you mean?
SS> I mean, AFAICS, it does so only for the joinable threads,
SS> while for the detached ones, it probably never blocks.
SS> Why it have to wait, if I would explicitly use wxThread::Wait()
SS> anyway? And if wxThread::Delete() is already coded that way,
SS> then maybe some other method is needed, which will only do
SS> wxThreadInternal::SetCancelFlag() and nothing more?
What good would do to you? If you don't want to wait for the thread to
finish, you could just as well not Delete() it at all...
Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Vadim Zeitlin wrote:
> I see. Hasn't there been a serial communications library announced here
This one?
http://www.iftools.com/ctb.en.html
Nice, thanks for the hint. But it looks way too
simplistic...
> some time ago? Maybe it has read with timeout?
It seems like it uses a non-blocking IO, and the
blocking-with-timeout functions are implemented as
simply a periodic polls.
I aim for something more robust (and that's why I
always have troubles, but that's the life :). I'd
like to avoid polling - instead I prefer the serial
port reader to send the events to the GUI thread
(I encapsulate the read data within these events).
As for timeouts - that library could probably use
select() for the better performance.
> SS> I think something like siginterrupt() with pthread_kill()
> SS> (haven't really tried, sorry, but should be trivial).
> Yes, of course -- with pthreads. I was speaking about portable solutions.
Why? Isn't wx about providing a portable solutions
by implementing them a non-portable OS-specific ways?
I mean, siginterrupt() with pthread_kill() will work on
unix, while on win32 there will be something else with
the similar effect.
> Also, to deal with the Java argument once and for all: Java threads are not
> OS threads to the best of my knowledge but just JVM abstraction and so they
> could design any threading behaviour they wanted.
AFAIK the things like gcj are using the native ways,
but I don't know too much about that.
> SS> wxThreadInternal::SetCancelFlag() and nothing more?
> What good would do to you?
It will make TestDestroy() to return true.
> If you don't want to wait for the thread to
> finish, you could just as well not Delete() it at all...
I *do* want to wait, but I am going to use Wait() for that,
not Delete(). IMHO that just resembles the APIs I am aware of.
pthread_cancel():
The cancellation processing in the target thread shall run asyn-
chronously with respect to the calling thread returning from
pthread_cancel().
After which I am supposed to do pthread_join().
If I want to kill the child process (not thread), again I
can send it the signal asynchronously and then do waitpid().
IMHO, the way wx implements wxThread::Delete() is counter-intuitive,
to say the least.
SS> > SS> I think something like siginterrupt() with pthread_kill()
SS> > SS> (haven't really tried, sorry, but should be trivial).
SS> > Yes, of course -- with pthreads. I was speaking about portable solutions.
SS> Why? Isn't wx about providing a portable solutions
SS> by implementing them a non-portable OS-specific ways?
SS> I mean, siginterrupt() with pthread_kill() will work on
SS> unix, while on win32 there will be something else with
SS> the similar effect.
No, to the best of my knowledge, there won't. Win32 doesn't support thread
cancellation.
SS> > SS> wxThreadInternal::SetCancelFlag() and nothing more?
SS> > What good would do to you?
SS> It will make TestDestroy() to return true.
And? If your worker thread never calls it, what does it change?
SS> IMHO that just resembles the APIs I am aware of.
SS> pthread_cancel():
pthread_cancel() doesn't work the same way as wxThread::Delete() at all,
if you expect them to work the same, you're going to have troubles.
Vadim Zeitlin wrote:
> SS> I mean, siginterrupt() with pthread_kill() will work on
> SS> unix, while on win32 there will be something else with
> SS> the similar effect.
> No, to the best of my knowledge, there won't. Win32 doesn't support thread
> cancellation.
You probably meant to say "Win32 doesn't support the interruption
of the blocked IO operations"? Since Thread.interrupt() is about
just that, AFAIK.
> SS> It will make TestDestroy() to return true.
> And? If your worker thread never calls it, what does it change?
That's the trick. I make TestDestroy() to return true
and then, before calling Wait(), I interrupt the IO
with Thread.interrupt(), so that it will call TestDestroy().
I.e. I want to stick some code between the delete notification
and waiting, which is what I can't do with wxThread::Delete().
If I interrupt the IO before notifying the thread, I'll have
a race condition.
SS> Vadim Zeitlin wrote:
SS> > SS> I mean, siginterrupt() with pthread_kill() will work on
SS> > SS> unix, while on win32 there will be something else with
SS> > SS> the similar effect.
SS> > No, to the best of my knowledge, there won't. Win32 doesn't support thread
SS> > cancellation.
SS> You probably meant to say "Win32 doesn't support the interruption
SS> of the blocked IO operations"? Since Thread.interrupt() is about
SS> just that, AFAIK.
What's the difference with what I wrote? IO functions provide a
cancellation point in pthreads, but there is no pthread_cancel() equivalent
in Win32.
SS> > SS> It will make TestDestroy() to return true.
SS> > And? If your worker thread never calls it, what does it change?
SS> That's the trick. I make TestDestroy() to return true
SS> and then, before calling Wait(), I interrupt the IO
SS> with Thread.interrupt(), so that it will call TestDestroy().
I don't know what exactly do you mean by Thread.interrupt but there is no
such thing in Win32 API as I tried to make it clear since the beginning of
the thread. In Win32 the simplest way to do what you need is use
MsgWaitForMultipleObjects() to wait on an event (which you'd signal from
the main thread to make the thread stop) and the IO handle.
Am Montag 08 Mai 2006 01:32 schrieb Stas Sergeev:
> Hi.
>
> Vadim Zeitlin wrote:
> > I see. Hasn't there been a serial communications library announced here
>
> This one?
> http://www.iftools.com/ctb.en.html
> Nice, thanks for the hint. But it looks way too
> simplistic...
>
> > some time ago? Maybe it has read with timeout?
>
> It seems like it uses a non-blocking IO, and the
> blocking-with-timeout functions are implemented as
> simply a periodic polls.
> I aim for something more robust (and that's why I
> always have troubles, but that's the life :). I'd
> like to avoid polling - instead I prefer the serial
> port reader to send the events to the GUI thread
> (I encapsulate the read data within these events).
> As for timeouts - that library could probably use
> select() for the better performance.
Why too simplistic? You can implementing this behaviour 'simply' with the ctb
library. There exist an plattform independent Ioctl call, with it you (or a
thread of your application) can find out, if there are some bytes in the
internal OS controlled buffer. And you can do this with the normal Read()
function (UNIX like).
The ctb library doesn't need any timeouts. The main thing of the design of the
ctb library is it's non-blocking implementation. For example:
char bug[100]
com = wxSerialPort()
com.Open(wxCOM1,...)
readed = com.Read(&buf,sizeof(buf))
if(readed > 0) {
// make some stuff, for example, send an event...
}
The last Read call NEVER blocks, also if there are no received bytes. And it
works with Linux, Windows, perhaps Mac OSX...
This is my opinion for a 'robust' design. Make it as simple as possible, and
add the GUI specific stuff in the GUI, not in the serial communication
library.
In my next release of ctb, also a 'ungetc()' function will be added, where you
can put back some to much readed bytes. This will also work with the GPIB
class and in the opposition of the clib 'ungetc' you can put more than one
byte back into the serial stream.
P.S. Some words to the performance. The ctb library works in our serial
analyser, which recorded all events of a serial connection up to 230400 Baud.
All events means: It recorded all level changes (valid, logical linestates
also of the RxD and TxD events. On a 115200 Baud connection, our analyser can
recording up to 100000 event in one second. Every event will be transfered
via 961600 Baud to the PC with 24 Bytes, so we get over 2 MBytes of data in
one second (a internal buffer in the analyser equalize the high data peaks).
All data will be received by a separate worker thread in our analyser
software (programming with wxWidget).
So I think, performance isn't any problem ;-) And neither the select() call in
unix doesn't improve the performance nor the the Windows specific 'serial
data available notification' call).
If you have any question about wxCTB, please let me know.
Best regards
Joachim
SS> OK, I beleive you, but still, IMHO, this is not the
SS> reason for not providing an ability to stick some code in
SS> between the delete notification and Wait(). Thread.interrupt()
SS> is just a missing feature - if it is not possible to implement
SS> on Win32 (I have to look up the gcj sources after all), then
SS> I could at least do such a thing on unixes by hands for my program
Well, it could hardly be a good guideline for designing wxThread API to
allow for the things which the class itself should support but doesn't.
Make no mistake, I don't like the current API neither but poking holes in
it is not going to make it better.
SS> And I don't think this is the only possible scenario where the one
SS> would want to do something between delete notification and Wait().
SS> The thread can just ignore the delete notifications completely
SS> until "something happens", and that "something" is probably
SS> supposed to come from the main thread.
You should do this something before calling Delete().
SS> That's why I thought the current implementation of Delete() is a
SS> misfeature.
Maybe but we can't really change its semantics without confusing people
even more (and breaking their code as a bonus). So all we can do is to add
some Cancel() method but if all it does is to set the internal flag which
TestDestroy() would examine later without actually waking it up, I don't
see how is it more useful than just having your own bool field in
YourThread object and YourCancel() and YourIsCancelled() functions.
Vadim Zeitlin wrote:
> SS> and then, before calling Wait(), I interrupt the IO
> SS> with Thread.interrupt(), so that it will call TestDestroy().
> I don't know what exactly do you mean by Thread.interrupt but there is no
> such thing in Win32 API
OK, I beleive you, but still, IMHO, this is not the
reason for not providing an ability to stick some code in
between the delete notification and Wait(). Thread.interrupt()
is just a missing feature - if it is not possible to implement
on Win32 (I have to look up the gcj sources after all), then
I could at least do such a thing on unixes by hands for my program
(not that I necessary will but at least there is a possibility).
But with Delete() doing also Wait(), I can't do that at all if
I am going to use Delete() rather than doing everything by hands.
And I don't think this is the only possible scenario where the one
would want to do something between delete notification and Wait().
The thread can just ignore the delete notifications completely
until "something happens", and that "something" is probably
supposed to come from the main thread.
That's why I thought the current implementation of Delete() is a
misfeature. Also the fact that it is blocking for joinable threads
and non-blocking for the detached threads, is IMO confusing. It
looks like such an implementation leaves the wxThread::Wait() of
no use at all.
Joachim Buermann wrote:
> Why too simplistic? You can implementing this behaviour 'simply' with the ctb
> library.
As far as I understand from the quick glance, your lib
needs a continous attention from the main thread, i.e.
it needs polling. I am trying to avoid polling if possible,
and I beleive this is the case.
> There exist an plattform independent Ioctl call, with it you (or a
> thread of your application) can find out, if there are some bytes in the
> internal OS controlled buffer.
Again, this is very nice probably only if I do polling.
If you use some async notifications, then perhaps this
information is of no use, so, while the implementation
became more complex, the API may get simpler.
> char bug[100]
> com = wxSerialPort()
> com.Open(wxCOM1,...)
> readed = com.Read(&buf,sizeof(buf))
> if(readed > 0) {
> // make some stuff, for example, send an event...
> }
Am I right that this example lacks something important?
Namely, it does read and the rest only once, but I think
this should have to be done in the loop, which is polling.
> And neither the select() call in
> unix doesn't improve the performance nor the the Windows specific 'serial
> data available notification' call).
I guess you were doing select() with zero timeout from the
main thread (i.e. the same polling). Having the reader thread
that will always sit in the select() with the large timeout,
probably will add something. (this is what I am going to try
shortly for myself)
So the only problem I see with your lib (and that's just IMHO)
is that it does really support only one way of reading the data,
which is the non-blocking IO with polling. Having the support
also for the blocking IO (with separate reader thread, so that
the main thread would still never block) would probably be not
that bad. But I agree this may be too much of a complexity for
the general-purpose lib. OTOH, this will probably allow to
remove the ioctl you were referring to, making an API smaller.
Vadim Zeitlin wrote:
> SS> until "something happens", and that "something" is probably
> SS> supposed to come from the main thread.
> You should do this something before calling Delete().
Obviously in most of the sane scenarious this is possible,
but at least in case of the Thread.interrupt() - it is not
(unless I avoid the Delete() completely). Of course I can't
claim that I can find another such an example, but who knows... :)
> I don't
> see how is it more useful than just having your own bool field in
> YourThread object and YourCancel() and YourIsCancelled() functions.
That's certainly true. It is just that I still haven't got
used to the fact that I have to add the code to my prog
that actually belongs to wx. For some strange reason I
still prefer to patch wx here and there and link statically,
but this gives more and more of the headache as the patches
accumulate (a small amount of them stuck at SF without any
comments), so eventually I'll probably start doing what you
suggest. :) Yes, in this particular case the addition would
actually be too small to even worry, but my concern is also
that wx probably have quirks if I have to do that.
You can do this also from a worker thread. Let doing the serial stuff by a
worker thread has a lot of advances. The serial data reading or writing is
independent from the state of your main thread. For example, you start a
modal dialog in the main thread, which blocks the execution, or you have a
expendable graphic output which consuming a lot of time.
>
> > There exist an plattform independent Ioctl call, with it you (or a
> > thread of your application) can find out, if there are some bytes in the
> > internal OS controlled buffer.
>
> Again, this is very nice probably only if I do polling.
> If you use some async notifications, then perhaps this
> information is of no use, so, while the implementation
> became more complex, the API may get simpler.
ok, i can handle this by implementing a automatically started notification
thread, which creates a signal, an event or something else, which you can
receive by your GUI. (The notification means: Data available for read, data
are written, linestates are changed and so one). But this makes the ctb
depending on a GUI library (like wxWidget), and ctb is also used in some
embedded systems, where neither is any GUI available nor exist any
display ;-)
And you have to read the data (after notification) quickly enough to avoid
data wastage by a full input buffer. What, if your application (main thread)
couldn't react in the right time?
>
> > char bug[100]
> > com = wxSerialPort()
> > com.Open(wxCOM1,...)
> > readed = com.Read(&buf,sizeof(buf))
> > if(readed > 0) {
> > // make some stuff, for example, send an event...
> > }
>
> Am I right that this example lacks something important?
> Namely, it does read and the rest only once, but I think
> this should have to be done in the loop, which is polling.
ok, a little bit clearer (and sorry for the grammatical errors - english is
not my native language and I learning by doing ... ;-)
void worker_thread(int* quit)
{
char buf[100];
com = wxSerialPort();
com.Open(wxCOM1,...);
while(!*quit) {
int rd = com.Read(&buf,sizeof(buf));
if(rd > 0) {
// handle the data, (send an event, write it in a fifo
// or something else
}
else {
// reduce the cpu last by doing a sleep (defined in
// ctb/timer.h)
sleepms(10);
}
}
}
With the quit pointer you can tell the worker thread to finish with a safety
way. But this only works, if there exist no blocking call in the thread.
>
> > And neither the select() call in
> > unix doesn't improve the performance nor the the Windows specific 'serial
> > data available notification' call).
>
> I guess you were doing select() with zero timeout from the
> main thread (i.e. the same polling). Having the reader thread
> that will always sit in the select() with the large timeout,
> probably will add something. (this is what I am going to try
> shortly for myself)
No, on linux I simply open the serial device as NON BLOCKED. The most code in
the Linux open call handle the special properties of a serial RS232 device
like baudrate, protocoll, wordlen, start/stopbits and so on...
The Read(...) and Write(...) of the wxSerialPort class are just a wrapper
function for the standard libc read/write (very easy ;-)
So a select() call isn't necessary - and the implementation becomes less
complex.
On Windows, the situation is a little bit more complex. Take a look in the
sources.
An Opening was doing by this:
fd = CreateFile(devname, // device name
GENERIC_READ | GENERIC_WRITE, // O_RDWR
0, // not shared
NULL, // default value for object security ?!?
OPEN_EXISTING, // file (device) exists
FILE_FLAG_OVERLAPPED, // asynchron handling
NULL); // no more handle flags
The trick is the FILE_FLAG_OVERLAPPED flag on the open call to make all reads
and writes asynchron, means: the function returns immediately and never
blocks. In the Read() and Write() function some additional win32 api calls
consider this behaviour.
BTW. On windows there exist no select() function and you have to use a
WaitForMultipleObjects call. Take a look in the description of this function
(or WaitForMultipleObjectsEx) and how you can use it - THIS IS COMPLEX!
>
> So the only problem I see with your lib (and that's just IMHO)
> is that it does really support only one way of reading the data,
> which is the non-blocking IO with polling. Having the support
> also for the blocking IO (with separate reader thread, so that
> the main thread would still never block) would probably be not
> that bad. But I agree this may be too much of a complexity for
> the general-purpose lib. OTOH, this will probably allow to
> remove the ioctl you were referring to, making an API smaller.
A blocking call is a hazardous thing, also in a reader thread. If your reader
thread blocks and you finish your main thread, you run in some problems with
windows, because windows doesn't allow to kill a running thread (in the
microsoft documentation you will be warned, if you doing that. One thread
(main) can terminate another thread with the TerminateThread function, but
the thread's resources will not be deallocated, completion handlers will not
be executed and attached DLL's will not be notified, so TerminateThread usage
is strongly discouraged.
This was one of the reasons, why I decide to realize a non-blocking access.
Ok, you can give a defined timeout, but if you want to initiate a measuring
equipment, in some circumstances, the timeout have to be a couple of seconds
(10s or more), and if you want to break down the initialisation, your main
thread has to wait, until the reader/worker thread with the blocking call was
finished. With the result, that your application doesn't show any reaction
for the user, who only want to exit the program quickly.
BTW: ctb also gives you the possibility, to read/write data with a given
timeout which can also be infinite.
For instance:
int rd = Readv(char* buf,size_t len,unsigned int timeout_in_ms);
This call returns only, if len bytes are received, or the timeout was reached.
You also can combine some read/write calls with one global timeout. This is
useful, if you have a communication with some reads and writes within a given
time and you doesn't want to check the timeout condition for every operation.
int toflag = 0;
char buf[100];
// timer instance with 1000ms
timer t(1000,&quit);
// set the toflag to 1 after 1s
t.start();
int rd = com.Readv(buf,sizeof(buf),&toflag);
...
if(toflag) {
// oops, something going wrong
}
Summarizing:
If you want to avoid polling, you can carry out this part to the OS (like
select() or WaitForMultipleObjects(Ex), WaitForSingleObjects(EX)) with the
disadvantage, that this call blocks. Ok, you can do this in a separate
thread, but than you have to kill the blocked thread in some circumstances.
You can also give a very short timeout, but than you also have to poll, so I
doesn't see any benefits in this way.
Or you are 'polling' the device with nonblocked calls. wxWidget Applications
without a high performance can do this in the OnIdle() function.
Take a look to our wxterm application on:
http://www.iftools.com/wxterm.en.html
This program handles all reading/writing in the OnIdle() function and works
with RS232 and GPIB. You can download the sources and also an executable
windows and linux version.
High performance application should use a special worker thread.
The ctb library is designed for this - and it also works with the GPIB device.
If you have to work with the standard National GPIB functions ibrd, ibwrt and
so on (all are blocking), and used these functions directly in a event driven
application, your application always 'paused' if there is no data available,
if communication errors occurs and more.
ctb also implements the GPIB IO processing with asynchrone reading/writing,
with the result, that you get also a non blocking GPIB access.
Best regards
Joachim
Joachim Buermann wrote:
> ok, i can handle this by implementing a automatically started notification
> thread, which creates a signal, an event or something else, which you can
> receive by your GUI. (The notification means: Data available for read, data
> are written, linestates are changed and so one).
But I think you can send not only the notifications.
Why sending a notification that linestat changed, if
you can just send that new linestat itself? Actually,
I am even sending the data itself via the events too.
That make an API very small.
> But this makes the ctb
> depending on a GUI library (like wxWidget), and ctb is also used in some
> embedded systems, where neither is any GUI available nor exist any
> display ;-)
OK, that's the good point. :) I thought it is specially
designed for wx, as it is called libwxtcb.
But you will probably agree that the wx users may prefer
something that depends on wx, in case it provides a
superior functionality, or at least has a simpler API.
> And you have to read the data (after notification) quickly enough to avoid
> data wastage by a full input buffer.
That's exactly one of those problems that I avoid by
incapsulating the data within an event. I also need a
precise timing, so I put a timestamp into an event too.
> What, if your application (main thread)
> couldn't react in the right time?
If I don't have to read the data immediately (like in your
approach), then I loose nothing - wx can queue the pending
events, and they already have the right timestamps too.
> (defined in
> // ctb/timer.h)
> sleepms(10);
What if I need to measure the timing with the higher
precision than this? Usually you can't even usleep() less
than for 10ms, but if you are blocked on read, then the
response time is smaller by an order of magnitude, and then
you can timestamp your data with the much higher accuracy.
> With the quit pointer you can tell the worker thread to finish with a safety
> way. But this only works, if there exist no blocking call in the thread.
Or with select() - it is blocking but has a timeout.
> The Read(...) and Write(...) of the wxSerialPort class are just a wrapper
> function for the standard libc read/write (very easy ;-)
> So a select() call isn't necessary - and the implementation becomes less
> complex.
I implemented Read() the way it uses select(). With select()
in use, it probably doesn't even matter whether you opened the
device file in a blocking or non-blocking mode.
Advantages:
1. Much smaller response time, compared to the 10ms sleeps.
2. Better CPU utilization - no polling, read() occures only
when there is really something to read.
Disadvantages:
1. A few more lines of code.
2. Not very portable to Win32, as you pointed out. :(
I don't know yet whether I will have to port that to Win32,
and other than that, I think it is a good choice.
> BTW. On windows there exist no select() function and you have to use a
OK. I have to admit that I am porting my progs to Win32 only
if I am really pressed, so I am not very familiar with its API.
But at least I think the cygwin can help overcoming such an
incompatibilities. Yes, obviously it is not suitable for your
lib. I can only speak about my own case then.
> A blocking call is a hazardous thing, also in a reader thread. If your reader
> thread blocks and you finish your main thread, you run in some problems with
> windows, because windows doesn't allow to kill a running thread
Yes, but that's what select() solves completely, offering you
a configurable timeout. You can also use the non-blocking mode -
with select() it probably doesn't matter much.
> Ok, you can give a defined timeout, but if you want to initiate a measuring
> equipment, in some circumstances, the timeout have to be a couple of seconds
> (10s or more)
Why? Unlike in the case of the polling, you are not supposed
to sleep() between the select() invocations. You only check the
exit condition and *immediately* get back to select(). That
should give you the best results *no matter* what the timeout
is. While in case of the polling you are forced to reduce the
usleep() value to the possible minimum, because there it really
hurts the precision. My point is that with select() you improve
the precision and response time by an order of magnitude, reducing
the CPU usage somewhat at the same time.