0 / 0 / 0
Регистрация: 27.02.2023
Сообщений: 11
1

Проблема с синхронизацией потоков Pthread

27.02.2023, 01:42. Показов 577. Ответов 2

Author24 — интернет-сервис помощи студентам
У меня есть программа, которая вызывает в отдельном потоке функцию потока ядра.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "otca.h"
 
//Подключение логики систем
//MAIN PANEL
#include "avionics/main_panel.h"
//TIME LOGIC
#include "avionics/time_logic.h"
 
//Переменные потоков систем
//TIME LOGIC
pthread_t time_logic_thread;
//MAIN PANEL
//acs
pthread_t main_panel_acs_thread;
 
void * OTCA_CORE_SIM(void * opaque){
    PROP_CYCLE CYCLE;
    sem_init(&CYCLE.core_semaphore, 0, 0);
    pthread_mutex_init(&CYCLE.cycle_mutex, NULL);
    pthread_cond_init(&CYCLE.cycle_condition, NULL);
    OTCA_CORE_STRUCT *OTCA_CORE_DATA = (OTCA_CORE_STRUCT*)opaque;
 
    //запуск систем
    //TIME LOGIC
    pthread_create(&time_logic_thread, NULL, time_logic_update, (void *) &CYCLE);
    //MAIN PANEL
    //acs
    pthread_create(&main_panel_acs_thread, NULL, main_panel_acs_update, (void *) &CYCLE);
 
    CYCLE.all_operations = 2;
 
    while (OTCA_INIT_SIM_RUN == 1) {
        //Подготовка отсчета времени цикла
        clock_t cycle_start = clock();
 
        CYCLE.current_opperation = 0;
 
        fprintf(stdout, "### Sim Cycle Started ###\n\n");
 
        //Выдача разрешений на выполнение
        //TIME LOGIC
        time_logic_run();
        time_logic_passed(); //Функция ожидающая прохождения time_logic
        //MAIN PANEL
        //acs
        main_panel_acs_run();
 
        fprintf(stdout, "-- Sim Systems Run --\n");
        //Ожидание завершения симуляции
        sem_wait(&CYCLE.core_semaphore);
        //OTCA_SYSTEM_WAIT();
        //while (1) {
            //pthread_mutex_lock(&CYCLE.cycle_mutex);
            //pthread_cond_wait(&CYCLE.cycle_condition, &CYCLE.cycle_mutex);
            //fprintf(stdout, "-- Here I am and %d\n", CYCLE.current_opperation);
            //pthread_mutex_unlock(&CYCLE.cycle_mutex);
            //break;
        //}
 
        //Подсчет времени обработки симуляции
        OTCA_CORE_DATA->cycle_time = (double)(clock() - cycle_start) / CLOCKS_PER_SEC;
 
        //Ожидание конца симуляции
        Sleep((uint32_t)((OTCA_INIT_SIM_PERIOD - OTCA_CORE_DATA->cycle_time) * 1000));
        fprintf(stdout, "\n### Sim Cycle Passed ###\n\n");
 
    }
 
    //Выгрузка потоков систем
    //TIME LOGIC
    pthread_detach(time_logic_thread);
    //MAIN PANEL
    //acs
    pthread_detach(main_panel_acs_thread);
 
    pthread_cond_destroy(&CYCLE.cycle_condition);
    pthread_mutex_destroy(&CYCLE.cycle_mutex);
 
    return NULL;
}
И вызывает она в также отдельных потоках функции систем, я сокращу алгоритм работы внутри этих функций, так как он не особо важен.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <semaphore.h>
 
#include "otca/properties.h"
#include "otca/functions.h"
 
#include "time_logic.h"
 
//time_logic
sem_t time_logic_work; //разрешающий семафор
sem_t time_logic_wait; //блокирующий семафор
void time_logic_run() {
    sem_post(&time_logic_work);
}
void * time_logic_update(void * opaque) {
    PROP_CYCLE *CYCLE = (PROP_CYCLE*)opaque;
    sem_init(&time_logic_work, 0, 0);
    sem_init(&time_logic_wait, 0, 0);
 
    double time_last = SIM_TIME.total_running_time_sec; // time for previous frame
    double last_m = FLIGHTMODEL_POSITION.M;
 
    while (OTCA_INIT_SIM_RUN) {
        sem_wait(&time_logic_work);
 
        //time calculations
        double time_now = SIM_TIME.total_running_time_sec;
            double passed = fabs(time_now - time_last);
            double curent_m = FLIGHTMODEL_POSITION.M;
            //print(passed)
            if (curent_m - last_m == 0) {
                passed = 0;
            }
            if (passed > 0.1) {
                passed = 0.1;
            }
 
            //TIME.frame_time = passed;
 
            //last variables
            time_last = time_now;
            //last_m = curent_m
 
        fprintf(stdout, "Time logic Passed\n");
        pthread_mutex_lock(&CYCLE->cycle_mutex);
        CYCLE->current_opperation = CYCLE->current_opperation + 1;
        fprintf(stdout, "Time logic data = %d\n",CYCLE->current_opperation);
        if (CYCLE->current_opperation == CYCLE->all_operations) {
            pthread_cond_broadcast(&CYCLE->cycle_condition);
        }
        pthread_mutex_unlock(&CYCLE->cycle_mutex);
        sem_post(&time_logic_wait);
    }
    sem_destroy(&time_logic_work);
    sem_destroy(&time_logic_wait);
    return NULL;
}
void time_logic_passed() {
    sem_wait(&time_logic_wait);
}
Аналогично вызывается логика acs.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <semaphore.h>
 
#include "otca/properties.h"
#include "otca/functions.h"
 
#include "main_panel.h"
 
//acs
sem_t main_panel_acs_work; //разрешающий семафор
sem_t main_panel_acs_wait; //блокирующий семафор
void main_panel_acs_run() {
     sem_post(&main_panel_acs_work);
}
void * main_panel_acs_update(void * opaque) {
    PROP_CYCLE *CYCLE = (PROP_CYCLE*)opaque;
    sem_init(&main_panel_acs_work, 0, 0);
    sem_init(&main_panel_acs_wait, 0, 0);
 
    uint8_t sec_mode[] = {0, 0, 0}; // chrono mode. 0 - reset, 1 - run, 2 - hold
 
    double chrono_sec_angle[] = {0, 0, 0}; // chrono sec needle
    double chrono_min_angle[] = {0, 0, 0}; // chrono min needle
    double sec_time[] = {0, 0, 0}; // chrono counter
    double start_sec[] = {0, 0, 0}; //time, when chrono started
 
    //flight timer variables
    double flight_mode[] = {0, 0, 0};
    double flight_time[] = {0, 0, 0};
    double flight_hour_angle[] = {0, 0, 0};
    double flight_min_angle[] = {0, 0, 0};
    double start_flight[] = {0, 0, 0};
 
    uint8_t knob_last = 0;
 
    while (OTCA_INIT_SIM_RUN) {
        sem_wait(&main_panel_acs_work);
 
        //Тут просто логика симуляции, с ней проблем нет
 
        fprintf(stdout, "ACS Logic Passed\n");
        //pthread_mutex_lock(&CYCLE->cycle_mutex);
        CYCLE->current_opperation = CYCLE->current_opperation + 1;
        fprintf(stdout, "ACS data = %d\n",CYCLE->current_opperation);
        if (CYCLE->current_opperation == CYCLE->all_operations) {
            fprintf(stdout, "HAPPY WORK = %d\n",CYCLE->current_opperation);
            sem_post(&CYCLE->core_semaphore);
 
        }
        //pthread_mutex_unlock(&CYCLE->cycle_mutex);
        sem_post(&main_panel_acs_wait);
    }
    sem_destroy(&main_panel_acs_wait);
    sem_destroy(&main_panel_acs_work);
    return NULL;
}
void main_panel_acs_passed() {
    sem_wait(&main_panel_acs_wait);
}
При вызове потока ядра симуляция зависает с таким выводом:
### Sim Cycle Started ###

-- Sim Systems Run --


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

### Sim Cycle Started ###

Time logic Passed
Time logic data = 1
-- Sim Systems Run --
ACS Logic Passed
ACS data = 2
HAPPY WORK = 2

### Sim Cycle Passed ###


С чем может быть проблема, почему могут не выполняться другие потоки и как это можно исправить ?

Пробовал несколько вариантов решения проблемы, особо ничего не помогает.

Структура PROP_CYCLE:
C
1
2
3
4
5
6
7
typedef struct PROP_CYCLE {
        int current_opperation;
        int all_operations;
        sem_t core_semaphore;
        pthread_mutex_t cycle_mutex;
        pthread_cond_t cycle_condition;
    } PROP_CYCLE;
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.02.2023, 01:42
Ответы с готовыми решениями:

Проблема с синхронизацией процессов
Здравствуйте, форумчане. Пишу небольшой клиент-сервер с таким заданием: клиент посылает число,...

Синхронизацией потоков посредством семафоров
Приветствую. Пишу многопоточное приложение с синхронизацией потоков посредством семафоров. Почему...

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

Photon проблема с синхронизацией
Проблема вот в чем) Игра в 3d. Все в общем хорошо кроме одного но. При подключении игроков на сцену...

2
6340 / 3511 / 1427
Регистрация: 07.02.2019
Сообщений: 8,977
27.02.2023, 02:12 2
Лучший ответ Сообщение было отмечено LexaVeter как решение

Решение

Цитата Сообщение от LexaVeter Посмотреть сообщение
С чем может быть проблема, почему могут не выполняться другие потоки и как это можно исправить ?
Увидел первую ошибку, дальше не вникал:
у вас из главного потока вызывается функция time_logic_run,
которая обращается к потенцально неициализированному семафору time_logic_work,
который инициализируется внутри функции потока time_logic_update.
Это UB. Инициализировать все нужно в главном потоке до старта рабочих потоков.
1
0 / 0 / 0
Регистрация: 27.02.2023
Сообщений: 11
27.02.2023, 05:52  [ТС] 3
Вывел инициализацию семафоров в отдельные функции
C
1
2
3
4
void main_panel_init() {
    sem_init(&main_panel_acs_work, 0, 0);
    sem_init(&main_panel_acs_wait, 0, 0);
}
А также написал отдельную функцию инициализации, еще до вызова потока ядра:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Функция запуска симуляции
void OTCA_INIT_SIM_START() {
    //Установка переменной управления потоком
    OTCA_INIT_SIM_RUN = 1;
    //Установка переменной периода симуляции
    OTCA_INIT_SIM_PERIOD = 0.02;
    //Инициализация компонентов
    OTCA_INIT_PROP_COMP();
    //Инициализация семафоров
    time_logic_init();
    main_panel_init();
    //Запуск потока core
    pthread_create(&core_thread, NULL, OTCA_CORE_SIM, (void *) &OTCA_CORE_DATA);
}
Результат порадовал, симуляция пошла, вывод такой:
### Sim Cycle Started ###

Time logic Passed
Time logic data = 1
-- Sim Systems Run --
ACS Logic Passed
ACS data = 2
HAPPY WORK = 2

### Sim Cycle Passed ###


Со всеми системами вывод такой:
Time logic Passed
Time logic data = 1
ACS Logic Passed
ACS data = 2
Clock24 Logic Passed
Clock24 data = 3
SVS Logic Passed
SVS data = 4
-- Sim Systems Run --
Termo Logic Passed
Termo data = 5
EUP53 Logic Passed
UAP14 Logic Passed
Mach meters Logic Passed
UVID-15FK Logic Passed
Mech Aneroid Logic Passed
UAP14 data = 7
HAPPY WORK = 10
UVID-15FK data = 9
HAPPY WORK = 10
EUP53 data = 6
HAPPY WORK = 10
Mach meters data = 8
HAPPY WORK = 10
Mech_aneroid data = 10
HAPPY WORK = 10


Ну тут понятно, что раскомментировать мьютексы надо, что я уже сделал, теперь все работает как часики, спасибо)
0
27.02.2023, 05:52
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.02.2023, 05:52
Помогаю со студенческими работами здесь

Проблема с синхронизацией объектов
Доброго дня, возникла проблема с network transform а точнее с синхронизацией объектов. У меня есть...

Проблема с вертикальной синхронизацией
Всем привет, столкнулся с такой проблемой. Построил проект, все работает, картинка в 60 фпс,...

проблема с синхронизацией Lotus Traveler
День добрый! Такая проблемка возникла: Существует две учетные записи, ссылающиеся на однин...

STM32F429 + LTDC+ VGA - проблема с синхронизацией.
Купил отладочную плату Core429I (на ней установлены STM32F429IGT6 и SDROM IS42S16400J). Изготовил...

проблема с синхронизацией звука через MIDI-клавиатуру
Прикупила я, значит, клавиши (MIDI-клавиатура) - 7 октав, контроллеров немерено и прочие...

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

Синхронизация потоков: проблема гонки потоков
Есть проблема в синхронизации потоков, которую я не знаю, как решить. Точнее у меня получается...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

Новые блоги и статьи
Как подключить JavaScript файл в другом JavaScript файле
InfoMaster 20.01.2025
В современной веб-разработке организация кодовой базы играет ключевую роль в создании масштабируемых и поддерживаемых приложений. Модульность и правильное структурирование кода стали неотъемлемыми. . .
Как откатить изменения в исходниках, не внесенные в Git
InfoMaster 20.01.2025
При работе с системой контроля версий Git разработчики часто сталкиваются с необходимостью отменить внесенные изменения в исходном коде. Особенно актуальной становится ситуация, когда изменения еще. . .
В чем разница между px, in, mm, pt, dip, dp, sp
InfoMaster 20.01.2025
В мире цифрового дизайна и разработки интерфейсов правильный выбор единиц измерения играет ключевую роль в создании качественного пользовательского опыта. История развития систем измерений для. . .
Как изменить адрес удалённого репозитория (origin) в Git
InfoMaster 20.01.2025
В терминологии Git термин origin является стандартным именем для основного удаленного репозитория, с которым взаимодействует локальная копия проекта. Когда разработчик клонирует репозиторий с. . .
Как переместить последние коммиты в новую ветку (branch) в Git
InfoMaster 20.01.2025
При работе над проектом часто возникают ситуации, когда необходимо изолировать определенные изменения от основной линии разработки. Это может быть связано с экспериментальными функциями, исправлением. . .
Как вернуть результат из асинхронной функции в JavaScript
InfoMaster 20.01.2025
Асинхронное программирование представляет собой фундаментальную концепцию в JavaScript, которая позволяет выполнять длительные операции без блокировки основного потока выполнения программы. В. . .
Какой локальный веб-сервер выбрать
InfoMaster 19.01.2025
В современной веб-разработке локальные веб-серверы играют ключевую роль, предоставляя разработчикам надежную среду для создания, тестирования и отладки веб-приложений без необходимости использования. . .
Почему планшеты и iPad уже не так популярны, как раньше
InfoMaster 19.01.2025
Эра революционных инноваций История планшетов началась задолго до того, как эти устройства стали привычными спутниками нашей повседневной жизни. В начале 1990-х годов появились первые прототипы,. . .
Как самому прошить BIOS ноутбука
InfoMaster 19.01.2025
BIOS (Basic Input/ Output System) представляет собой важнейший компонент любого компьютера или ноутбука, который обеспечивает базовое взаимодействие между аппаратным и программным обеспечением. . .
Какой Linux выбрать для домашнего компьютера
InfoMaster 19.01.2025
Современные реалии выбора операционной системы В современном мире выбор операционной системы для домашнего компьютера становится все более важным решением, которое может существенно повлиять на. . .
Как объединить два словаря одним выражением в Python
InfoMaster 19.01.2025
В мире программирования на Python работа со словарями является неотъемлемой частью разработки. Словари представляют собой мощный инструмент для хранения и обработки данных в формате "ключ-значение". . . .
Как без исключения проверить существование файла в Python
InfoMaster 19.01.2025
При разработке программного обеспечения на Python часто возникает необходимость проверить существование файла перед выполнением операций с ним. Это критически важная задача, которая помогает избежать. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru