Multithreaded C Program on the Raspberry PI

cmultithreadingpthreadsraspberry pi

Currently, I am having a hard time to discover what the problem with my multithreading C program on the RPi is. I have written an application relying on two pthreads, one of them reading data from a gps device and writing it to a text file and the second one is doing exactly the same but with a temperature sensor. On my laptop (Intel® Core™ i3-380M, 2.53GHz) I am have the program nicely working and writing to my files up to the frequencies at which both of the devices send information (10 Hz and 500 Hz respectively).

The real problem emerges when I compile and execute my C program to run on the RPi; The performance of my program running on RPi considerably decreases, having my GPS log file written with a frequency of 3 Hz and the temperature log file at a frequency of 17 Hz (17 measurements written per second)..

I do not really know why I am getting those performance problems with my code running on the PI. Is it because of the RPi has only a 700 MHz ARM Processor and it can not process such a Multithreaded application? Or is it because my two threads routines are perturbing the nice work normally carried out by the PI? Thanks a lot in advance Guys….!!!

Here my code. I am posting just one thread function because I tested the performance with just one thread and it is still writing at a very low frequency (~4 Hz). At first, the main function:

int main(int argc, char *argv[]) {
    int s1_hand = 0;
    pthread_t routines[2];
    printf("Creating Thread -> Main Thread Busy!\n");

    s1_hand = pthread_create(&(routines[1]), NULL, thread_2, (void *)&(routines[1]));

    if (s1_hand != 0){
        printf("Not possible to create threads:[%s]\n", strerror(s1_hand));
        exit(EXIT_FAILURE);
    }
    pthread_join(routines[1], NULL);

    void* result;
    if ((pthread_join(routines[1], &result)) == -1) {
        perror("Cannot join thread 2");
        exit(EXIT_FAILURE);
    }
    pthread_exit(NULL);

    return 0;
}

Now, thread number 2 function:

void *thread_2(void *parameters) {
    printf("Thread 2 starting...\n");
    int fd, chars, parsing, c_1, parse, p_parse = 1;
    double array[3];
    fd =  open("dev/ttyUSB0", O_RDONLY | O_NOCTTY | O_SYNC);
    if (fd < 0){
        perror("Unable to open the fd!");
        exit (EXIT_FAILURE);
    }
    FILE *stream_a, *stream_b;
    stream_a = fdopen(fd, "r");
    stream_b = fopen (FILE_I, "w+");
    if (stream_a == NULL || stream_b == NULL){
        perror("IMPOSSIBLE TO CREATE STREAMS");
        exit(EXIT_FAILURE);
    }
    c_1 = fgetc(stream_a);
    parse = findit(p_parse, c_1, array);
    printf("First Parse Done -> (%i)\n", parse);
    while ((chars = fgetc(stream_a)) != EOF){
        parsing = findit(0, (uint8_t)chars, array);
        if (parsing == 1){
            printf("MESSAGE FOUND AND SAVED -> (%i)\n", parsing);
            fprintf(stream_b,"%.6f %.3f %.3f %.3f\n", time_stamp(), array[0], array[1], array[2]);
        }
    }
    fflush(stream_b);

    fclose(stream_b);
    fclose(stream_a);

    close(fd);

    pthread_exit(NULL);

    return 0;
} 

Note that on my thread 2 function I am using findit(), function which returns 0 or 1 in case of having found and parsed a message from the gps, writing the parsed info in my array (0 no found, 1 found and parsed). The function time_stamp() just call the clock_gettime(CLOCK_MONOTONIC, &time_stamp) function in order to have a time reference on each written event. Hope with this information you guys can help me. Thank you!

Best Answer

Obviously the processor is capable of running 20 things a second. I'd first check your filesystem performance.

Write a small program that simulates the writes just the way you're doing them and see what the performance is like.

Beyond that, I'd suggest it's the task swapping that's causing delays. Try without one of the threads. What type of performance do you get?

I'd guess it's the filesystem, though. Try buffering your writes into memory and do large (4k+) writes every few seconds and I bet that will make your system a lot happier.

Also, post your code. Otherwise all we can do is guess.