Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
1786 / 1036 / 445
Регистрация: 12.05.2016
Сообщений: 2,550

Вызов функций с разными интервалами в одном цикле

30.05.2017, 17:48. Показов 1933. Ответов 9

Студворк — интернет-сервис помощи студентам
Здравствуйте! Подскажите, как правильно реализовать вызов функций с разными интервалами? Точность не важна(+-5мин), время выполнения функций тоже.
C
1
2
3
4
5
6
while (1) {
    f0();  // вызов каждые 5 мин
    f1();  // вызов каждые 30 мин
    f3(); // вызов каждые 180 мин
    // ? sleep(5);
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.05.2017, 17:48
Ответы с готовыми решениями:

Вызов нескольких функций в цикле по имени
Хочу сделать в цикле запрос функций в стиле NumberLayers = 4 for i = 1, NumberLayers do //Какой-то повторяемый код ...

График с разными интервалами
как построить такой график в excel?

Вызов функций с циклами одновременно в одном окне
Обе функции содержат циклы. Что нужно сделать чтобы циклы работали одновременно в одном окне? Совет(Поместить всё в один цикл) не...

9
20 / 20 / 9
Регистрация: 25.11.2016
Сообщений: 105
02.06.2017, 00:54
Как реализовать: например так:
засыпать на 5 минут в конце цикла, считать количество засыпаний.
тогда f0() нужно оставить так как есть, а на остальные повесить условие - вызывать если счетчик кратен 6 и 36 соотв.

Добавлено через 1 минуту
Как правильно - нужно уточнить для чего это нужно, иначе задача выглядит синтетической.
1
1786 / 1036 / 445
Регистрация: 12.05.2016
Сообщений: 2,550
02.06.2017, 08:06  [ТС]
Цитата Сообщение от MihaelK Посмотреть сообщение
Как правильно - нужно уточнить для чего это нужно, иначе задача выглядит синтетической.
MihaelK, согласен, сейчас примерно так и сделано: глобальная переменная в которой хранится счетчик, а в конце цикл засыпает на минимальный из интервалов, а функции выполняются по ифу, завернуто все это в макрос чтобы можно было любую функцию по таймеру вызывать. Хотелось бы узнать, может есть в линухе что-то готовое для этого? В гугле искал, но ничего подобного не нашел, может сформулировал вопрос не так.
0
20 / 20 / 9
Регистрация: 25.11.2016
Сообщений: 105
02.06.2017, 17:07
Цитата Сообщение от shvyrevvg Посмотреть сообщение
Хотелось бы узнать, может есть в линухе что-то готовое для этого?
Может и есть:
Цитата Сообщение от MihaelK Посмотреть сообщение
нужно уточнить для чего это нужно, иначе задача выглядит синтетической
0
 Аватар для qwarta
73 / 73 / 11
Регистрация: 20.11.2009
Сообщений: 238
03.06.2017, 17:39
Еще вариант:
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
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
 
volatile sig_atomic_t flag = 0;  
 
void f0(void) 
{
    printf("_____ f0()_____\n");
}
 
void f1(void) 
{
    printf("_____ f1()_____\n");
}
 
void f2(void) 
{
    printf("_____ f2()_____\n");
}
 
void handle(int sig)             // обработчик сигнала
{
    flag++;      
    f0();                         
    if ((flag % 6) == 0)         // 30 минут
        f1();
    if ((flag % 36) == 0)        // 180 минут
        f2();
    alarm(300);                  // 5 минут
}
 
int main(void) 
{
    signal(SIGALRM, handle);     // ловит сигнал и вызывает наш обработчик
    alarm(1);                    // посылаем SIGALRM
    while(1) 
        {
            ;                    // не спим, делаем что-нибудь полезное
        }
    return 0;
}
1
 Аватар для qwarta
73 / 73 / 11
Регистрация: 20.11.2009
Сообщений: 238
05.06.2017, 00:15
А вот попытка реализовать через потоки не удалась, что-то лыжи не едут. Код работает... как ему вздумается. Если, ничего не меняя, перекомпилировать - вывод изменится. Где-то накосячил...
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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
 
void f0(void) 
{
    printf("  f0()\n");
}
 
void f1(void) 
{
    printf("  f1()\n");
}
 
void f2(void) 
{
    printf("  f2()\n");
}
    
 
void *thread_start(void *arg)
    {
        if (*((int*)arg) == 0)
            {
                printf("_______New1: ");
                for (;;)
                    {
                        sleep(5); //sleep(300)
                        f0();
                    }
            }
        if (*((int*)arg) == 1)
            {
                printf("_______New2: ");
                for (;;)
                    {
                        sleep(11); //sleep(1800)
                        f1();
                    }
            }
        if (*((int*)arg) == 2)
            {
                printf("_______New3: ");
                for (;;)
                    {
                        sleep(23); //sleep(10800)
                        f2();
                    }
            }
        return((void *)0);
    }
    
int main(void)
{
    int err, max = 3;
    pthread_t tid[max];
    
    for (int i = 0; i < max; i++)
        {
            err = pthread_create(&tid[i], NULL, thread_start, &i);
            if (err != 0)
                {
                    printf("невозможно создать поток: %s\n", strerror(err));
                    return 0;
                }
        }
    sleep(3);
    for (int i = 0; i < max; i++)
        {
            pthread_join(tid[i], NULL);
        }
    printf("_______Main:\n");
    return 0;
}
1
20 / 20 / 9
Регистрация: 25.11.2016
Сообщений: 105
05.06.2017, 01:20
qwarta, когда нити создаются им в качестве параметра передаётся адрес i.
т.е. все три нити запускаются с одинаковым параметром.
Далее читается значение по этому адресу, которое может быть 0, 1, 2 или вообще мусор
т.к. переменная живет внутри цикла, а нить не обязана стартануть до завершения цикла.
(тем самым ловим неопределенное поведение.)

Выход - передавать само значение, а не адрес на него.
2
 Аватар для qwarta
73 / 73 / 11
Регистрация: 20.11.2009
Сообщений: 238
05.06.2017, 17:35
не обязана стартануть
И ведь книга перед носом, и написано в ней черным по белому:
При создании нового потока нельзя заранее предполагать, кто первым получит управление - вновь
созданный поток или поток, вызвавший функцию pthread_create.

Не по теме:

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

0
 Аватар для Olej
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
09.06.2017, 15:32
Лучший ответ Сообщение было отмечено shvyrevvg как решение

Решение

В таких асинхронных случаях в Linux наилучший способ - это независимые потоки.
Цитата Сообщение от MihaelK Посмотреть сообщение
Выход - передавать само значение, а не адрес на него.
Цитата Сообщение от qwarta Посмотреть сообщение
for (int i = 0; i < max; i++)
{
err = pthread_create(&tid[i], NULL, thread_start, &i);
Code
1
2
3
4
5
6
7
8
9
10
11
12
void *tfun( void *in ) {
   int t = *(int*)in;
   while( true ) {
      // ... здесь само действие f0, f1, f2 в зависимости от t
      sleep( t * 60 * ... ); // здесь интервал повторения f0, f1, f2
   }
}
...
   for( int i = 0; i < max; i++ ) {
      err = pthread_create( &tid[i], NULL, tfun, (void*)i );
      ...
   }
За локальность i можете не переживать, потому что в (void*)i передаётся копия значения (в вызов функции потока).
1
1786 / 1036 / 445
Регистрация: 12.05.2016
Сообщений: 2,550
09.06.2017, 16:42  [ТС]
MihaelK, qwarta, Olej, спасибо за помощь!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.06.2017, 16:42
Помогаю со студенческими работами здесь

Перезагружается Windows 7 с разными интервалами
Всем привет. Дали системник который периодически (с разными интервалами) перезагружается. Сначала думал что что-то перегревается, но HW...

Периодично с разными интервалами зависает Windows
Здравствуйте! Столкнулся с очень непонятной проблемой. После включения ПК запускаю google chrome, через некоторое время chrome...

Построение графика по точкам с разными доверительными интервалами
Доброго дня. Допустим, есть эксп. данные (1±0,5), (2±0,3), (3±0,15) и т.п. Существует непонимание, как построить кривую, на которой...

Итерационные циклы,Определение и вызов функций,Использование библиотечных функций stdio.h
Помогите решить задания: 1.Дано натуральное число n. Найти разность между первой цифрой этого числа и суммой всех остальных. ...

Передача значений функций в главную программу, вызов функций
Здравствуйте! Скорее всего, неправильно передаю значения функциям и в главную программу. Помогите найти ошибку! В итоге выводит...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru