Форум программистов, компьютерный форум, киберфорум
C (Си)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 05.03.2023
Сообщений: 17

Задача со звездочкой, на логику (про массив)

03.04.2023, 20:07. Показов 2152. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Придумал чепуху чтобы вы поломали головы. Есть массив
C
1
int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Нужно вывести его елементы в их порядке, то есть 0 1 2 3 4 5 6 7 8 9, но нужно ето сделать при помощи [B][I][U]двух[B][U][I] циклов, причем один цикл будет печатать парные индексы, а второй - непарные.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.04.2023, 20:07
Ответы с готовыми решениями:

Задача на логику, про путешественника и ограниченный бюджет
Путешественник располагает суммой Р рублей. Он может двигаться со скоростью 5км/ч бесплатно, со скоростью 40 км/ч за 14руб или со скоростью...

Подскажите про логику
Для расчета ставки надо знать: длительность операции, (первоначальную стоимость И величину периодического платежа) ИЛИ (первоначальную...

Задача про массив
Здравствуйте, дан массив А{1,2,3,4}. Нужно составить всевозможные комбинации этих чисел. Помогите понять, как реализовать это через...

35
фрилансер
 Аватар для Алексей1153
6502 / 5740 / 1134
Регистрация: 11.10.2019
Сообщений: 15,382
04.04.2023, 13:38
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Eddy_Em Посмотреть сообщение
для спокойствия душевного
не для этого, а для исключения неопределённого поведения же
0
Нарушитель
445 / 886 / 106
Регистрация: 23.11.2021
Сообщений: 5,203
Записей в блоге: 19
04.04.2023, 13:41
Итак, как и обещал. Вот код:
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
#include <stdio.h>
#include <pthread.h>
 
static int flage = 0, flago = 1;
#define MAXN    (100)
 
typedef struct{
    int *mylock;
    int *theirlock;
    int start;
} threaddata;
 
void *thread(void *arg){
    threaddata *d = (threaddata*)arg;
    for(int i = d->start; i < MAXN+1; i += 2){
        while(*d->mylock);
        printf("%d ", i);
        *d->mylock = 1;
        *d->theirlock = 0;
    }
    return NULL;
}
 
int main(int argc, char **argv){
    pthread_t threade, threado;
    threaddata e = {&flage, &flago, 1};
    threaddata o = {&flago, &flage, 2};
    pthread_create(&threade, NULL, thread, &e);
    pthread_create(&threado, NULL, thread, &o);
    pthread_join(threade, NULL);
    pthread_join(threado, NULL);
    printf("\n");
    return 0;
}
Вот выхлоп:
Code
1
2
gcc 1.c && ./a.out
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Добавлено через 20 секунд
Цитата Сообщение от Алексей1153 Посмотреть сообщение
для исключения неопределённого поведения же
Никакого неопределенного поведения в данном случае не будет! Сами подумайте, почему.
Сейчас набросаю вывод в 10 потоков чисел от 1 до 1000.
0
фрилансер
 Аватар для Алексей1153
6502 / 5740 / 1134
Регистрация: 11.10.2019
Сообщений: 15,382
04.04.2023, 13:59
собственно, объясни, почему тут не будет гонки? Я не понимаю. Пока что я вижу, что есть гонка


Цитата Сообщение от Eddy_Em Посмотреть сообщение
Сами подумайте, почему.
без оптимизации - да, не наблюдается. А у же с -O1 начались фокусы

я попробовал в компиляторе C и C++17 - одинаковое поведение (то есть, с оптимизацией - не работает)

добавил в C++ atomic (там это в одно движение делается) - и всё починилось
0
Нарушитель
445 / 886 / 106
Регистрация: 23.11.2021
Сообщений: 5,203
Записей в блоге: 19
04.04.2023, 14:10
Цитата Сообщение от Алексей1153 Посмотреть сообщение
начались фокусы
И действительно: черт знает что происходит... Хотя, по логике вещей не должно быть такого: ведь мы последовательно разрешаем запуск определенного потока, пока остальные ждут разблокировки. А выходит, что в определенный момент все внезапно стопорится.
atomic, кстати, не помогает, как и volatile.

Необъяснимым образом эта проблема решилась после того, как я вставил usleep:
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
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <stdatomic.h>
#include <unistd.h>
 
#define NTHREADS    (10)
#define MAXN        (1000)
 
static volatile int flags[NTHREADS] = {0};
 
void *thread(void *arg){
    int idx = *((int*)arg), next = (idx == NTHREADS-1) ? 0 : idx+1;
    for(int i = idx+1; i < MAXN+1; i += NTHREADS){
        while(flags[idx]) usleep(10);
        flags[idx] = 1;
        printf("%d ", i);
        flags[next] = 0;
    }
    return NULL;
}
 
int main(int argc, char **argv){
    pthread_t threads[NTHREADS];
    for(int i = 1; i < NTHREADS; ++i)
        flags[i] = i;
    for(int i = 0; i < NTHREADS; ++i)
        pthread_create(threads + i, NULL, thread, (int*)flags + i);
    for(int i = 0; i < NTHREADS; ++i)
        pthread_join(threads[i], NULL);
    printf("\n");
    return 0;
}
Работает и с -O0, и с -O3.
А без usleep оно или адски тормозило, или вообще зависало.
volatile можно убрать: и без него работает.

А вот попытка напечатать в 1000 потоков числа до 1млн тоже не вышла: зависло все к чертям (и заработало после увеличения паузы до 1000).
0
фрилансер
 Аватар для Алексей1153
6502 / 5740 / 1134
Регистрация: 11.10.2019
Сообщений: 15,382
04.04.2023, 14:19
Цитата Сообщение от Eddy_Em Посмотреть сообщение
atomic, кстати, не помогает
помогает, он работает на 100%

С++
https://onlinegdb.com/UXtPEOj4B

Цитата Сообщение от Eddy_Em Посмотреть сообщение
volatile
помочь и не может. Даже если будет казаться, что заработало. Он не для этого, и гонку он не убирает

Добавлено через 4 минуты
Цитата Сообщение от Eddy_Em Посмотреть сообщение
вставил usleep
даже это рано или поздно сломается Но и понятно, что никому не нужен код со слипом
0
Нарушитель
445 / 886 / 106
Регистрация: 23.11.2021
Сообщений: 5,203
Записей в блоге: 19
04.04.2023, 14:22
Цитата Сообщение от Алексей1153 Посмотреть сообщение
он работает на 100%
Я в С++ вообще 0 (а по ссылке еще и форматирования нет). Прошу код на С. Что нужно изменить в моем коде, чтобы без usleep работало?
Вообще не понимаю, где ломается моя логика: каждый поток ждет, пока его флаг станет равным нулю. Однако, это адово тормозит и даже "заедает". Т.е. какой-то поток, получив 0 в своем флаге, выходит из while, ставит себе 1 во флаг, но почему-то до printf дело не доходит, как и не доходит до разблокировки следующего потока.
0
фрилансер
 Аватар для Алексей1153
6502 / 5740 / 1134
Регистрация: 11.10.2019
Сообщений: 15,382
04.04.2023, 14:25
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Прошу код на С
я не занимался синхронизацией под C, поэтому пример буду делать долго и с ошибками

Цитата Сообщение от Eddy_Em Посмотреть сообщение
Что нужно изменить в моем коде, чтобы без usleep работало
добавить синхронизацию.
0
 Аватар для zayats80888
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
04.04.2023, 14:26
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Прошу код на С
В С11 добалена поддержка атомарных типов и операций. https://en.cppreference.com/w/c/atomic
0
Нарушитель
445 / 886 / 106
Регистрация: 23.11.2021
Сообщений: 5,203
Записей в блоге: 19
04.04.2023, 14:29
Цитата Сообщение от Алексей1153 Посмотреть сообщение
добавить синхронизацию.
Дык, в том-то и логика была, что никакой синхронизации не нужно, если в один момент лишь одному потоку разрешено выполнение.

Добавлено через 1 минуту
Цитата Сообщение от zayats80888 Посмотреть сообщение
добалена
Знаю, замена int на atomic_int у флагов ничего не меняет. Да и не должна, т.к. нет гонок же!
0
 Аватар для zayats80888
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
04.04.2023, 14:29
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Дык, в том-то и логика была, что никакой синхронизации не нужно, если в один момент лишь одному потоку разрешено выполнение.
А это самое "разрешение" вы как синхронизировать будете?
0
Нарушитель
445 / 886 / 106
Регистрация: 23.11.2021
Сообщений: 5,203
Записей в блоге: 19
04.04.2023, 14:30
zayats80888, зачем синхронизировать разрешение? Как только я изменил переменную, поток об этом узнал… Не может же кто-то другой установить этот флаг в 1 одновременно с разрешающим потоком!
0
фрилансер
 Аватар для Алексей1153
6502 / 5740 / 1134
Регистрация: 11.10.2019
Сообщений: 15,382
04.04.2023, 14:33
Eddy_Em, этап принятия необходимости синхронизации: торг
0
Нарушитель
445 / 886 / 106
Регистрация: 23.11.2021
Сообщений: 5,203
Записей в блоге: 19
04.04.2023, 14:36
В общем, сработало вот так - заменой флагов на мьютексы:
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
#include <stdio.h>
#include <pthread.h>
 
#define NTHREADS    (10)
#define MAXN        (1000)
 
static pthread_mutex_t mutexes[NTHREADS];
static int idx[NTHREADS];
 
void *thread(void *arg){
    int idx = *((int*)arg), next = (idx == NTHREADS-1) ? 0 : idx+1;
    for(int i = idx+1; i < MAXN+1; i += NTHREADS){
        pthread_mutex_lock(mutexes + idx);
        printf("%d ", i); fflush(stdout);
        pthread_mutex_unlock(mutexes + next);
    }
    return NULL;
}
 
int main(int argc, char **argv){
    pthread_t threads[NTHREADS];
    for(int i = 0; i < NTHREADS; ++i)
        pthread_mutex_lock(mutexes + i);
    for(int i = 0; i < NTHREADS; ++i){
        idx[i] = i;
        pthread_create(threads + i, NULL, thread, idx + i);
    }
    pthread_mutex_unlock(mutexes);
    for(int i = 0; i < NTHREADS; ++i)
        pthread_join(threads[i], NULL);
    printf("\n");
    return 0;
}
Ни хрена не понимаю, почему, но теперь работает. В том числе и досчитать до миллиона в 1000 потоков...
Да, fflush здесь тоже не нужен, т.к. только тормозит.
0
 Аватар для zayats80888
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
04.04.2023, 14:37
Цитата Сообщение от Eddy_Em Посмотреть сообщение
зачем синхронизировать разрешение? Как только я изменил переменную, поток об этом узнал… Не может же кто-то другой установить этот флаг в 1 одновременно с разрешающим потоком!
Суть синхронизации не только в атомарности, но и переупорядочивании/кэшировании операций как компилятором, так и процессором.
0
Нарушитель
445 / 886 / 106
Регистрация: 23.11.2021
Сообщений: 5,203
Записей в блоге: 19
04.04.2023, 14:43
До меня таки не доходит, откуда здесь взялись условия гонки и кто тот "вредный тип", который флаг меняет на 1, как только я его в 0 сброшу!
Я понимаю, бывают проблемы "гонок", когда в разных потоках пытаешься изменить значение одной и той же переменной (в итоге там может быть мусор какой-то), ну или доступ к ресурсам (в тот же сокет написать последовательно - нужны мьютексы). Но здесь совершенно элементарная задача - и таки без мьютексов не обойтись…

Что-то я со своими микроконтроллерами уже совсем далек стал от компьютера. Там-то все вообще просто: поток может быть только один, разве что прерывания периодически возникают. Но никаких блокировок и атомарных переменных не нужно вообще.
0
 Аватар для zayats80888
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
04.04.2023, 14:54
Eddy_Em, как минимум - в вашем коде из поста 24, вы передаете в поток указатель на флаг, который является и флагом и значением. Поэтому, если он будет изменен одним потоком до того, как прочитан другим в строке 13, вы получаете не то, что хотите.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.04.2023, 14:54

Задача про массив
Дано натуральное число N и массив из N целых чисел a1, a2, ..., an. Над элементами массива можно производить следующие действия: для любого...

Задача про массив
Здравствуйте помогите пожалуйста написать программу на Delphi 7. В визуальном варианте Дан массив A ненулевых целых чисел размера...

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

Про логику движения по окружностям
Вот часто смотрю на графические примеры с вращением или движением по окружности или дугам, и не понимаю, как пишут эту всю логику по...

Про логику работы игры
Итак, хочу попросить у вас помощи. Так как с логикой у меня туго) У меня есть игровое поле 700 на 450 пикселей, где существует мой...


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

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Новые блоги и статьи
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru