Test multi-thread program on one CPU

Today, I tested a multi-thread program on one CPU. The testbed is a FreeBSD virtual machine, and from lscpu command, it has indeed one CPU:

$ lscpu
Architecture:            aarch64
Byte Order:              Little Endian
Total CPU(s):            1
Model name:              Apple Unknown CPU r0p0 (midr: 610f0000)

The multi-thread program is simple too, just 4 threads add one global variable, and the correct result should be 400000 in every run. If the result is not 400000, exit the program:

#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>

#define THREAD_NUM 4
#define SUM_LOOP_SIZE 100000

uint64_t sum;

void *
thread(void *arg)
{
    for (int i = 0; i < SUM_LOOP_SIZE; i++) {
        sum++;
    }
    return NULL;
}

int
main()
{
    pthread_t tid[THREAD_NUM];
    uint64_t counter = 0;
    while (1) {
        counter++;
        for (int i = 0; i < THREAD_NUM; i++) {
            int ret = pthread_create(&tid[i], NULL, thread, NULL);
            if (ret != 0) {
                fprintf(stderr, "Create thread error: %s", strerror(ret));
                return 1;
            }
        }

        for (int i = 0; i < THREAD_NUM; i++) {
            int ret = pthread_join(tid[i], NULL);
            if (ret != 0) {
                fprintf(stderr, "Join thread error: %s", strerror(ret));
                return 1;
            }
        }

        if (sum != THREAD_NUM * SUM_LOOP_SIZE) {
            fprintf(stderr, "Exit after running %" PRIu64 " times, sum=%" PRIu64 "\n", counter, sum);
            return 1;
        }

        sum = 0;
    }

    return 0;
}

Built and run the program:

$ ./multi_thread_one_cpu
Exit after running 17273076 times, sum=200000
$ ./multi_thread_one_cpu
Exit after running 1539708 times, sum=100000

Change “uint64_t sum;” to “volatile uint64_t sum;“, compile and run again:

$ ./multi_thread_one_cpu
Exit after running 20 times, sum=200000
$ ./multi_thread_one_cpu
Exit after running 50 times, sum=200000

Exit much faster.

In summary, when there are multiple threads access same variable, always use lock. P.S., the code can be found here.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.