0
votes

i have a multithread application such that I connect sensors, (number of sensors is user depended) these sensors collect data and send them to my program via TCP. I take these data from TCP and do some complex calculations. After that I write my results to a shared memory space(for each sensor result i have different memory space.) For this purpose, I create 3 different class(for TCP, calculation, writing shared memory). And each class task run in parallel(task1 is TCP, task2 is calculation, task3 writing). Each task must be in while(1), because i want do each threads run until user stop program completely. If i have one sensor, i create one TCP object, one calculation object and one object for writing to shared memory, and i create 3 different thread for one TCP, one calculation and one writing. If i have 2 sensors have 2 objects for each and 2 threads for each and so on.

My problem is, because of using while loop, my cpu usage is always 100%. if i have 1 or 2 sensors, i have 3 or 6 different threads and everything works fine. But if i have much more sensors, for example 5, my program start to freeze. How do i prevent from freezing?

My code is basically;

void classTCP::threadTCP(){
    while(1){
        pthread_mutex_lock(&mutex1);
        pthread_cond_wait(&cond1, &mutex1);
        //..do_something
        pthread_mutex_unlock(&mutex1);
    }
}
void classCalculation::threadCalculation(){
    while(1){
        pthread_mutex_lock(&mutex2);
        pthread_cond_wait(&cond2, &mutex2);
        //..do_something
        pthread_mutex_unlock(&mutex2);
    }
}

void class3::thread3(){
    while(1){
        pthread_mutex_lock(&mutex3);
        pthread_cond_wait(&cond3, &mutex3);
        //..do_something
        pthread_mutex_unlock(&mutex3);
    }
}

int main()
{
    while(1)
    {
        pthread_cond_broadcast(&cond1);
        pthread_cond_broadcast(&cond2);
        pthread_cond_broadcast(&cond3);
        //...
    }
}
1
The fragment as posted doesn't make a whole lot of sense. What kind of events do your condition variables represent? What do the mutexes protect? - n. 1.8e9-where's-my-share m.
pthread_cond_wait must only be ever used in while loop, e.g. while(!cond) pthread_cond_wait;, lookup spurious wakeups. - Maxim Egorushkin
I want each sensor run synchronously, I mean program first get TCP message, after that do calculation and then write results. and each sensor do this in parallel. @n.'pronouns'm. - DikotaLolly
Looks pretty sequential to me. Get a message, do calculations., write the results. Why threads and mutextes and condvars and all this stuff? Maybe when you have two sensors, run them in two threads. Not six. - n. 1.8e9-where's-my-share m.
But each sensor connected different TCP ip/ports. I want to connect them at the same time? Am i wrong? @n.'pronouns'm. - DikotaLolly

1 Answers

2
votes

The problem is that you have many, many threads that are busy-waiting. They're not lazily waiting for input, they're actively looking if there's input.

The first improvement to make is to get rid of the excessive threads per sensor. The calculation thread spends its time waiting on the TCP thread. Similarly, each writer thread waits for a calculation thread That's just a waste. Just have a sensor thread that contains a "TCP read, calculate, write" loop.

Next, use a TCP blocking read. That takes about 0% CPU usage, until there's data available. Since you use just one thread per sensor, this also means you're using 0% CPU for calculations and writing.

A more modern approach would be Boost Asio, which calls your code when there is data available.