Является ли вызов функции «точки входа потока» в C «нормальной» функцией плохой практикой кода? - PullRequest
0 голосов
/ 25 января 2019

Недавно я столкнулся с очень специфической ситуацией, когда мне приходилось думать об использовании одной и той же функции как в «нормальном» вызове функции, так и в качестве функции «точки входа потока» с использованием потоков POSIX в C.

Позвольте мне лучше объяснить ситуацию: у меня есть программа, которая, в зависимости от выбора пользователя, должна выполнять разные задачи.

Две задачи очень похожи, но они отличаются в том смысле, что в одном случае один набор операций должен выполняться параллельно другому, а во втором случае вместо этого почти обязательно должен быть один и тот же набор операций. выполняется раньше другого, что исключает необходимость создания выделенного потока.

Поскольку «общий» набор операций очень похож в обоих случаях, я фактически написал код, подобный следующему:

if(task_type==0) {
    // Create two threads
    pthread_create(&tid[0],NULL,&common_operations,(void *) &args);
    pthread_create(&tid[1],NULL,&parallel_operations,(void *) &args);

    pthread_join(tid[0],NULL);
    pthread_join(tid[1],NULL);
} else if(task_type==1) {
    common_operations(&args); // Thread entry point function called as "normal function"
    sequential_operations(&args); // Different with respect to "parallel_operations"
}

Определение функции "common_operations" как:

static void *common_operations (void *arg) {
    // Properly casting void *arg to the right struct, containing, among the other things, "task_type"      

    // Function body....

    if(arg->task_type==0) {
        pthread_exit(NULL);
    } else {
        return NULL;
    }
}

Я никогда не видел функцию точки входа потока, используемую таким образом, и мне было интересно, можно ли это считать приемлемым или это плохая практика кода, чтобы смешивать вещи таким образом.

Кроме того, есть ли лучшие решения для этого конкретного случая?

1 Ответ

0 голосов
/ 25 января 2019

Конечно, можно вызывать «функцию потока», как и любую другую функцию.В этом нет ничего плохого, если вы преобразуете (приводите) в правильный тип, все должно быть в порядке.Является ли это хорошей практикой , субъективно.Это настолько необычно, что было бы трудно найти кого-то, кто бы называл это откровенно «плохой практикой, вы должны избегать»:)

Однако вы можете переписать немного так, чтобы «нормальная» функция против потокаРазличие функций ясно.И сделайте это void функцией, чтобы она не возвращала ничего в однопоточном вызове, что в противном случае выглядело бы немного странно.Это также позволит избежать потенциального спагетти-кода.

/* Use it in direct, single-threaded call */
static void common_operations(common_arg_type *arg) {
    // Function body....
}

/* Use it in pthread_create call */
static void *common_operations_thread(void *arg) {
    common_operations(args);
    return NULL; /* equivalent to pthread_exit(NULL); */
}

IMO, соображения, которые вы должны дать, одинаковы для любой многопоточной программы: функция остается поточно-ориентированной и любая функция, которую вы вызываете из функции потокатакже потокобезопасны и так далее.Иначе не о чем беспокоиться.

...