Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.1k views
in Technique[技术] by (71.8m points)

c - How to interrupt a fread call?

I have the following situation:

There is a thread that reads from a device with a fread call. This call is blocking as long as there is no data send from the device. When I stop this thread it remains hanging inside this thread.

Now I found the following inside the man page of fread:

ERRORS

On all systems that conform to the Single UNIX Specification, the fread() function sets errno as listed for the following conditions:

[EINTR] The read operation was terminated due to the receipt of a signal, and no data was transferred.

That would mean there is a way to interrupt the call from a different thread. But I have no idea how. Can someone tell me how to send a signal to interrupt the fread call? And what signal I need to send?


Update 08-10-10 09:25

I still haven't got it to work. I tryed the kill() and pthread_kill() with different signals. But nothing seems to interrupt the fread() call. The only thing that I got working is killing the entire application, but that's not what I want.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

1. Signals:

Using signals, as many others pointed out, would work. However, as many others also pointed out, the approach has its disadvantages.

2. Select():

Using select() (or other multiplexing function), you can block waiting for data to arrive from more than one file descriptor, and specify a timeout.

Use the timeout to your advantage. Whenever select() returns, check a global variable to see if you must terminate. If you want immediate reaction, keep reading.

3. Select() and pipes:

Multiple fds means you can wait for data arriving through the device you mentioned and, say, a pipe.

Before you create the thread, create a pipe, and then have the thread block on select() monitoring both the device and the pipe. Whenever you want to unblock select whether the device has new data or not, send a byte down the pipe.

If select() tells you it unblocked due to data arriving through the pipe, you can clean up and terminate. Note this method is much more flexible than the signaling method, since you can, besides just using the pipe as a wake-up method, use it to pass useful information or commands.

4. Select(), pipes and signals:

If you are using multiple processes and don't want to/can't pass around a pipe, you can combine both solutions. Create a pipe and install a signal handler for, say, SIGUSR1. In the signal handler, send a byte down the pipe.

Whenever a process sends SIGUSR1, the handler will be called and unblock select(). By examining the fdsets, you will know it was for no other reason than your own program signaling itself.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...