aborting a blocking read on linux
If you only want the signal to affect the read, use pthread_sigmask()
to keep the signal blocked until just before the read and to block it again afterwards.
Terminating blocking IO in Linux C++
read()
should not leak memory. With both blocking and nonblocking reads, the application code is still responsible for the management of the memory provided as the buf
argument. Interrupting read()
via a signal will not throw an exception, so if use signals, you will need to check the result and errno.
- If
read()
is interrupted by a signal before reading data, -1 will be returned with errno set toEINTR
. - If
read()
is interrupted by a signal after reading some data, POSIX allows for either -1 to be returned with errno set toEINTR
, or forread()
to return the number of bytes already read.
If you use pthread_cancel()
then an exception will be thrown. With this approach, you have the following options:
- Perform cleanup by registering cleanup functions with
pthread_cleanup_push()
. - Allocate dynamic memory, storing into thread specific storage via
pthread_setspecific()
. - Manage the memory via an
auto_ptr/unique_ptr
. - Catch the
abi::__forced_unwind
exception, perform cleanup, and rethrow.
In general, consider avoiding thread cancellation. When possible, it is better, and more manageable, to have a shared flag that is used to break out of the loop. This allows the thread to perform any necessary cleanup, and prevents your implementation from being dependent on your threading library's implementation and any of its quirks.
For your case, where you are using a blocking read, consider polling the fd to see if data is available via select()
with a timeout, and only call read()
if the fd has data. This allows you to periodically check if the thread flag is set to no longer run, and prevents you from needing to deal with signals to interrupt the thread from read()
, as read()
should no longer block waiting on data.
Also, the behavior that occurs when deleting a thread object is dependent on the thread library. For example, deleting a pthread_t
or boost::thread
has no effect on the associated thread's execution.
Linux, cancel blocking read()
One fairly popular trick: instead of blocking in read(), block in select() on both your serial-socket and a pipe. Then when another thread wants to wake up your thread, it can do so by writing a byte to the other end of that pipe. That byte will cause select() to return and your thread can now cleanup and exit or whatever it needs to do. (Note that to make this work 100% reliably you'll probably want to set your serial-socket to be non-blocking, to ensure that your thread only blocks in select() and never in read())
Abort a read() from another thread
Use pthread_kill() on the thread you want to signal. Don't use kill(); for that matter, since you linked to it, don't use signal() -- it's one of the more retarded, non-portable interfaces:
The behavior of signal() varies across UNIX versions, and has also
varied historically across different versions of Linux. Avoid its
use: use sigaction(2) instead. See Portability below."
[ This has been answered in the comments, but for some reason still shows up in the relevance top of unanswered questions. So here, for the sake of completeness ]
How to stop Linux read system call from blocking?
call
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
This will make the file descriptor non-blocking.
C: blocking read should return, if filedescriptor is deleted
The code you are describing has an inherent race condition - if another thread could be a in blocking read()
on a file descriptor when you close()
that file descriptor, the other thread could just as well be just about to call read()
instead.
You can't call close()
unless you know that all other threads are no longer in a position to be using that file descriptor at all.
The easiest way to handle cases like you describe is for one thread to be the 'owning' thread of each file descriptor, that is responsible for closing the file descriptor. Other threads don't directly close it - instead they mark the file descriptor as "to be closed" in some shared data structure and wake up the owning thread.
You can make it possible to wake the owning thread by having it not block in read()
but instead block in select()
or poll()
with another file descriptor - usually a pipe - in the set as well as the target file descriptor. The thread is woken by writing to the other end of that pipe.
How to abort a blocking process.getInputStream().read() with close()?
You tried close()
and it doesn't work. The only other thing I can think of to try is calling Thread.interrupt()
on the blocked thread ... but I doubt that that will work either.
The real issue is that the specs (i.e. respective javadocs) don't say whether these things will work. Even if they do work ... for some version of Java on some OS platform ... there is no guarantee that they will work on other version/platform combinations.
Trying to exit from a blocking UDP socket read
This really depends on what system you're running under. For example, if you're running under a POSIX-compliant system and your thread is cancelable, the recv() call will be interrupted when you cancel the thread since it's a cancel point.
If you're using an older socket implementation, you could set a signal handler for your thread for something like SIGUSR1 and hope nobody else wanted it and signal, since recv() will interrupt on a signal. Your best option is not to block, if at all possible.
How to make Bash's read abort after trapping interrupt?
Seems like not interrupting immediately is a Bash non-POSIX extension (see read_builtin
in read.def
of Bash builtin source (look for posixly_correct
)).
You can override this behavior, and exit on the first Ctrl+C
by forcing POSIX behavior for read
(by setting the POSIXLY_CORRECT
environment variable):
#!/bin/bash
trap 'echo $$ was interrupted' INT
POSIXLY_CORRECT=1 read foo
echo done
Related Topics
Profiling Arbitrary Cuda Applications
Remote Linux Server to Remote Linux Server Large Sparse Files Copy - How To
How to Install Packages in Tcl
What Is The Downside of Updating Arm Ttbr(Translate Table Base Register)
How to Measure Net Used Disk Space Change Due to Activity by a Given Process in Linux
Sendmail/Procmail - Get Mail Sender and Mail Subject, Utf8 Encoding Issues
Update .Bashrc from Provisioning Shell Script with Vagrant
Expect Utility Is Not Working When Executing from Jenkins
Disable CPU Caches (L1/L2) on Armv8-A Linux
Changing File Permissions Linux
Cmakelist File to Generate Llvm Bitcode File from C Source File
Shared Libraries in Same Folder with App in Tcsh
Can Inotify Tell Me Where a Monitored File Is Moved
Source Bashrc Doesn't Work in Cron