while inside a thread

hi guys,
I’ve got a program that read from several serial lines.
I’ve made a function that manage a single line and so I’ve assigned a thread for each port I must read.
the problem is that when each thread are up, the system is very very slow (about 3 seconds slower for each thread)…
I think that is because the function have a thing of this kind:

//inizialization of the port etc.. while (1) fread (str, len, n, fp);
I do this because data transmission is not regular or what, so I alway check if there is data on the port, if those data are validatedI start read all the message…

now my question is: is that a problem generated only from the while , so can I sobstitute it with another statement, or is a thread priority problem? or anything else that I 've not mentioned?

I reckon that the fread() call doesn’t block when no data is to be read. It just returns immediately with 0 bytes read, and because of the loop, that code never blocks and is executed as fast as the CPU allows, in fact consuming all CPU.

You should go for a design that blocks the caller until there is really some data to be read. If you read from /dev/ser# using the standard QNX serial drivers, you might want to use select() to make your thread go to sleep until data arrives on the port. The resource manager will wake you up, and only then you issue a read() to fetch the data. Perhaps you find an option to the serial driver that makes the read() call block until data available, which would eliminate the need for select().

Btw, a while(1) is a very common design for a thread that does its task in a cyclic fashion.

Regards,

Albrecht

"Perhaps you find an option to the serial driver that makes the read() call block until data available, which would eliminate the need for select(). "

You should change the transmission settings with struct termios. I think it was aprox. this way:

#include <termios.h>

struct termios newtio;
int fildes;

fildes=open ( … );
tcgetattr(fildes, &newtio);
newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=1;
//With VTIME=0 and VMIN=1 function ‘read’ will keep blocked until it receives
//at least one character.
tcsetattr(fildes,&newtio);

read( … );

I’m not sure about the fields of the functions, but if they’re not correct, they’re similar to the ones I’ve written.

or looking at readconf() function

I don’t know why but my problem is not related to the read(), but to the cread creation…

if I start my app there are thwo threads(coda and mark) which keep busy the system, so, when I use sh is veeeeery slow doing anything…

if I remove this two threads creation, the system speed become regular…

now, I can’t understand why it do all this, because the threads have the same initial settings…

if I use pidin, it shows me that Coda and Mark are the only two threads that have no values in the “blocked” col… the others threads have 8199 or 8200…

I don’t understand very well your post. Do you mean Coda and Mark have the same code as the rest of the threads? I do think the problem is the parameters of the reading function.

Most probably the read() is returning right way and not blocking. Check for error code.

I’m sorry if I can’t explain correctly my problems…however, I solved with a sched_yield(); when the cicle begins…
thanks

Put a sched_yield() in loop is hardly a solution, you really should check return values of the read()/fread(), and find out why if they are failing…

why?

Because in a real-time system you want the CPU to do as little work as possible.

The fact that you need to put sched_yield() to FORCE a rescheduling, means your thread is using all of the available CPU, that’s bad. That also means any program at lower priority then the thread will NEVER get to run.

More importantly that means there is something wrong with the behavior of read(), as it should BLOCK (thus not use any CPU) waiting for incomming data.

if I correctly understand this is already done by me…my problems are not the threads with read(), but the orher two threads (coda and Mark) which have no read() inside…