I'm developing an application over Qt.
In this application the main thread is a web server. Another thread sometimes read data from big files (250mb) and write them in a output file (~2gb).
This thread performs high I/O operation on file, and CPU iowait is around 70%.
My problem is that when writing into the file, the web server is not responding quickly. What i understood is that the server's qt socket (on Linux) is represented by a system socket connected to the poll or select event system. So Qt send signal to my application only when poll emit event.
What i think is that too huge io operation with file writing may block the poll system, so my qt server doesn't receive socket event. When the thread has finished to write its data, everything become normal.
The file writing look like this:
while(dataToRead){
// context has the list of files to read and current step
dataToRead = extractData(context, &pBuffer, &sizeBuf);
fwrite (pBuffer, 1, sizeBuf, pOutFile);
free(pBuffer);
pBuffer = NULL;
// usleep(100000);
}
If i add a break with usleep function, this help to avoid the problem but not completely if i don't use a big enough sleep. But too big sleep destroy the performance, and i was the file generated as fast as possible.
What i'm doing wrong? Is it safe to read/write into a file as fast as possible? Is a sleep is mandatory in the above function? But how can we know the good timeslice?
I'm working on Mint LMDE, Linux 3.2.0 64 bits with Intel Core i5 2500 and standard HDD drive.
Edit:
A sample program that reproduce the problem is available here: https://bugreports.qt-project.org/secure/attachment/30436/TestQtBlocked.zip. Need qt's qmake to compile it. If you run it, it will create an empty 3GB file, the worker thread will be launched at startup and will create the file during few seconds. During this time, if you try to connect to http:// localhost:8081/ and you run many F5 to refresh the page, you will see that sometime it's not responding quickly.
If could be helpful if someone can reproduce my problem with my sample program, and let me know.
If you are starving the main thread's select calls, create a separate thread to do the file I/O. When the event comes from Qt, trigger some kind IPC that wakes up your worker thread to do the big file I/O and return from your event handler immediately.
(This assumes that writing to the file asynchronously makes sense to your program logic. Only you can figure out if that is true.)
from the man page:
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
You want to write sizeBuf , 1 element.
You may want to tune buffering with setvbuf.
setvbuf(pOutfile, NULL, _IONBF, 0) - to disable buffering.
Complete example at:
http://publib.boulder.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Frtref%2Fsetvbuf.htm
better switch to work with file descritors, not file streams.
Using file descriptors you can use sendfile and slice.
man sendfile
man slice
Related
My application needs to read files from a nfs mount point. I'm using QFile::read(BUFFER_SIZE); which works as it is supposed to. The problem is, when the nfs unmounts (patchy network issues), this QFile::read() never timesout resulting in application hang. Any sensible solutions please?
Thanks.
You can use QFile::bytesAvailable () inherited from QIODevice which returns the number of bytes that are available for reading. Wait in a while loop until the bytes are available or some seconds elapsed :
QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QElapsedTimer timer;
timer.start();
while(file.bytesAvailable()<BUFFER_SIZE || timer.nsecsElapsed()<3e9)
qApp->processEvents();
QByteArray array
if(file.waitForReadyRead())
{
array = file.read(BUFFER_SIZE);
}
Here it will wait 3 seconds for the data to be ready. The elapsed time is measured by QElapsedTimer. If BUFFER_SIZE bytes are not available after the timeout then it will continue with out hanging.
I think this is due to how NFS works. The process is stuck in the OS system call, in uninterruptible sleep. So, I think you have two reliable options:
Move file reading to another thread. It and its event loop may get stuck, just code your main thread so that it won't matter for the whole application. There are a few ways to go about using threads for this, but if you are not reading arbitrary number of different files at the same time, it'd probably be best to launch a dedicated thread for reading the single file, and then let the thread finish once everything is read. For this, you might even just subclass QThread, and override run() method with your own reading loop (you can still emit signals for progress if you want, you just can't receive them queued without Qt's event loop).
Move file reading to another process. In other words, write a small tool program or script which does the actual reading, and sends the contents to your main process. That way you should be able to kill the reading process without killing the whole application, should that become necessary. Again you have to decide if you want a separate single-use process for each reading (so you can give file name as command line paramater, for example), or if you launch one child process and implement communication with it so you can request files (or parts of files). Qt's QProcess makes this approach easy, too.
You can use QIODevice::readChannelFinished() signal and connect it to a slot that close the file reader
I am building an application that intersepts a serial comunication line by recieving the transmition, modifieng the data, and echoing the changed result.
The transmitted data is made of status sentances at high baudrate with alot of data.
I have created two threads, one reads the sentaces and pushes a pointer to each new sentance into a queue, and the Other pops the pointers out of the queue, manipulates them, sends them to the serial port and deletes the pointer.
The queue operstions are in external functions with CririticalSection locks so that works fine.
To make sure the queue doesnt overflow quickly i need to send the messages quickly and not wait for the recieving to end.
To my understanding serial ports can recieve and transmit simultaniously but trying to do so gives error with access resttictions.
The other solution is to split the system into two diffrent ports but I try to avoid it because the hardware changes and the need of another USB and convertor.
I read about Overlapped structures but didnt fully understood what is their usage and, as I got it they manage asinc operation where my issue is parallel operation.
Sorry for my lame english, any help or explanation will help.
I used this class for the serial comunication, setting overlapped to enable when opening the comport to allow wait event timeouts:
http://www.codeproject.com/Articles/992/Serial-library-for-C
Thanks in advance.
Roman.
Clarification:
Im not opening the port twice, just once in the main program and pass the handler to both threads (writing it now maximizes the problem in this approach
More details:
The error comes from the Cserial library:
"Cserial::read overlapped complete without result." Commenting the send back to serial command in the sending thread will not raise an error and the queue is filled and displays correctly–
Im on a classified system without internet access so i cant upload the sample, writing from my tablet. The error accures after I get the first sentace, which triggers the first send command ss soon as queues size changes, and then the recieving thread exits because recieve failes, so the queue stops to fill and nothing sends out.
Probbly because both use same serial handler but whats the alternative to access the same port simultaniosly without locking one thread or the other
Ignoring error 996, which is the error id of the "read overlapped completed without results" and not exiting the thread when its detected makes both recieve an transmited data wrong (missing bytes)
At the buttom line, after asking alot of questions:
Why a read operation is interrupted by a write operation if these are two seperate comunication lines?can i use two handlers one for each task on the same port?
Is the D+/- in usb is transmit/recieve or both line used for transmit and recieve?
":read overlapped complete without result"
Are you preventing the read from being interrupted by the OS switching execution to the write thread? You need to protect this from happening by using a mutex or similar.
The real solution is to switch to an asynchronous library, such as bosst::asio.
Why a read operation is interrupted by a write operation if these are two seperate comunication lines?
here is a possible hand-waving visualization of what happens if you use synchronous operations in two threads without locking them against each other. ( I am guessing at the details of how you arranged your software )
Your app receives a read request from the port.
Your app requests the OS to start the read thread.
OS agrees, and your read thread completes the read.
-. Your app does its processing.
Your app asks the OS to start the write thread.
The OS agrees, and your write thread starts a write.
A second read request arrives on the port. This does not interrupt anything, it just waits.
The write is not yet finished, but the OS decides that the write thread has had enough time. It decides to switch context to the read thread which is waiting.
The read thread starts reading
Again the OS decides that the running thread ( read ) has had a fair crack at the CPU . It switches context back to the write thread. This crashes the unfinished read. Note that this happens in your software, not in the hardware, or the hardware driver.
This should give you a general insight into the sort of problems that occur, unless you keep the OS from running the reads and writes over the top of each other. It is a matter of opinion wehter it is better to use multithreading with mutexes ( or equivalent ) or asynchronous event-driven designs.
Two threads can't operate on single port / file descriptior. Depending on what library you used you should try to do this asynchronous or by checking how many bytes can be read/write without blocking thread. (if it is Linux raw filedescriptor you should look at poll / select)
My application records audio samples from a microphone connected to my PC. So I chose the Windows WaveInXXX API to do the job.
After reading the documentation I decided to avoid using the callback mechanism with WaveInProc to save me the hassle synchronizing the threads. The whole application is pretty big and I thought this would make debugging simpler. When the application requests a block of samples, I just iterate over my buffer queue, take one out, copy the data, unprepare it, prepare it and add it back to the buffer queue. Basic program structure looks like this, I hope it makes the basic program flow clear:
WaveInOpen()
WaveInStart()
FunctionAddingPreparedBuffersToTheQueue()
while(someConditionThatEventuallyBecomesFalse)
if(NextBufferInQueueIsMarkedDone)
GetDataFromBuffer()
UnpreparePrepareHeaderAndAddBuffer()
else
WaitForAShortTime()
WaveInStop()
WaveInClose()
Now the problem appears: After some time (and I am unable to reproduce the exact condition), WaveInAddBuffer() causes a deadlock although it's in the same thread as all the rest. The header for the buffer that shall be added when the deadlock happens is prepared and dwFlags == WHDR_PREPARED == 2.
Any ideas what could cause this deadlock?
I have not seen such a problem, but a guess might be something like fragmentation related to all the unprepare/prepare cycles. They are not necessary. You can do the prepare once for each buffer and then unprepare when finished recording. (Prepare locks the buffer into physical memory.)
I have a problem with my multithreaded networking server program.
I have a main thread that is listening for new client connections. I use Linux epoll to get I/O event notifications. For each incoming event, I create a thread that accept() the new connection and assign a fd to it. Under heavy loading, it can occur that the same fd is assigned twice causing my program to crash.
My question is: how can the system re-assign a fd that is still used by another thread?
Thanks,
Presumably there is a race condition here - but without seeing your code it's hard to diagnose.
You would be better to accept on the Main thread and then pass the accepted socket to the new thread.
If you pass your listening socket to a new thread to then perform the accept - you're going to hit a race condition.
For further information you can look here: https://stackoverflow.com/a/4687952/516138
And this is a good background on networking efficiency (although perhaps a bit out of date).
You should call accept() on the same thread that you are calling epoll() on. Otherwise you are inviting race conditions.
File descriptors are modified in a "per process basis". This means that they are unique for each process. This means that multiple threads can share the same file descriptors in the same process.
Having an accept syscall returning the same file descriptor inside the same process is a very strong indication that some of your threads are closing the previous "version" of the repeated file descriptor.
Issues like this one may be difficult to debug in complex software. A way to identify that in Linux system is to use the strace command. One can run strace -f -e trace=close,accept4,accept,pipe,open <your program>. That's going to output on your screen the respective syscalls specified in the command along with which thread is calling it.
I'm reading a big file using fread. When I interrupt the program during it using Ctrl+C, the program hangs and is not killable, also not with kill -9. It simple sticks with 100% CPU, keeping the RAM it had already allocated. It would be great to get that fixed, but it would also be okay just to be able to kill that application from outside (the main problem being the fact that I can't restart that machine myself).
Is there a way of doing that in Unix?
Thanks!
Here is the source:
int Read_New_Format(const char* prefix,const char* folder)
{
char filename[500];
long count_pos;
//open files for reading.
sprintf(filename,"%s/%s.pos.mnc++",folder,prefix);
FILE *pos = fopen(filename,"r");
if(pos==NULL)
{
printf("Could not open pos file %s\n",filename);
}
//read the number count of entries in each of the three files.
fread(&count_pos,sizeof(long),1,pos);
printf("[...]");
//read the complete file into an array.
float *data_pos = new float[3*count_pos];
fread(data_pos,3*sizeof(float),*count_pos,pos);
printf("Read files.\n");
[...]
}
If your program cannot be interrupted by a signal, that almost surely means it's in an uninterruptable sleep state. This is normally an extremely short-lived state that only exists momentarily while waiting for the physical disk to perform a read or write, either due to an explicit read or write call that can't be satisfied by the cache, or one resulting from a page fault where a disk-backed page is not swapped into physical memory.
If the uninterruptable sleep state persists, this is almost surely indicative of either extremely high load on the storage device (a huge number of IO requests all happening at once) or, much more likely, damaged hardware.
I suspect you have a failing hard disk or scratched optical disc.
Problem wasn't reproducable after some days. Maybe a problem with the file system. As a workaround, direct use of the unix library routines instead of fread worked.