Ответы пользователя по тегу Многопоточность
  • Как исправить ошибку "Кадр не находится в модуле" при создании потока?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    "Кадр не находится в модуле". Подскажите с чем это может быть связано
    HANDLE h = CreateThread(
        NULL,
        0,
        factorial(gn),
        NULL,
        NULL,
        NULL
    );

    Третий параметр CreateThread -- указатель на функцию, которая будет запущена в создаваемом потоке. А у тебя записано скорее всего что-то другое. Если ты хотел запустить функцию factorial в потоке, она должна 1) иметь определённый прототип (вот такой), и 2) в функцию CreateThread надо передать её адрес, а не результат её вызова (например, так: CreateThread(NULL, 0, factorial, NULL, NULL, NULL)). 3) если ты сделаешь эти два изменения, тебе прийдётся также переделать передачу параметра в функцию factorial и получение результата её работы.
    Ответ написан
  • Как продолжить выполнение кода, не дожидаясь завершения потока?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    типа того:
    #include <iostream>
    #include <thread>
    #include <vector>;
    
    using namespace std;
    
    void go(int p) {
      while (1) {
        cout << p << endl;
      }
    }
    
    void main() {
      thread *t[3];
    
      for (int i = 0; i <= 2; i++) {
        t[i] = new thread(go, i);
        cout << 123;
      }
      for (int i = 0; i <= 2; i++) {
        t[i]->join();
        delete t[i];
      }
    }
    Ответ написан
    Комментировать
  • Что такое Потоки на уровне ОС? В 1-ядерном процессоре же всего 1 поток?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    И К примеру выполняется такие команды, как пример инструкция чтения строки из stdin, почему вся ос не глохнет. Типа что в этот момент ожидания времени происходит, Или что ОС все 1000 потоков переключает там каждую 0.0001 секунды?

    Только готовые к выполнению потоки получают процессорное время. Потоки могут останавливаться в ожидании какого-либо примитива синхронизации, например семафора или мьютекса. Такие потоки не занимают процессор.
    Поток читающий из stdin может останавливаться, например, на семафоре, защищающем очередь данных stdin когда она пуста. Какой-то другой поток должен поместить новые данные в очередь stdin и открыть этот семафор, переведя ожидающий поток в состояние готовности к выполнению.
    Ответ написан
    Комментировать
  • Корректно ли из разных потоков вызывать одну и ту же функцию?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    это нормальная практика, или может быть какая ошибка в случае, когда 2 объекта А одновременно вызывают метод из Б?

    Зависит от того как устроен и куда обращается этот метод. Если он прямо или косвенно обращается к изменяемым глобальным данным без синхронизации или использования атомарного доступа -- может быть ошибка.

    Например, обращение к любой из переменных global/class_static/function_static в следующем коде -- потенциальная ошибка:
    int global;
    
    class B
    {
        static int class_static;
    public:
        void f()
        {
            static int function_static;
        }
    };
    Ответ написан
  • Есть ли какие-нибудь паттерны или фрейворки для программирования под многоядерные ARMы?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    Есть ли какие-нибудь ... технологии в языках, ориентированные на многоядерность?

    OpenMP.
    Ответ написан
    Комментировать
  • Насколько хорошим решением является использование pthread_kill для возобновления работы потоков?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    Насколько хорошим решением является использование сигналов для выведения потоков из спящего режима, и стоит ли для этого использовать ...

    Является решением, но не самым традиционным. Насколько хорошим -- зависит от модели совместной работы потоков/того как разделяются данные между ними. Не хватает контекста для ответа.
    Ответ написан
  • Как правильно прервать поток в Си?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    Общее правило при работе с потоками, не специфичное для С или pthreads: состояние резделяемое между потоками должно быть или атомарным или должно быть защищено примитивом синхронизации.
    Код функции thread_process никак не гарантирует, что компилятор не выкинет проверку !quit, потому что quit не меняется в этой функции и в функциях вызываемых из неё.

    Учитывая, что атомарность и потоки вошли в стандарт С11 имеет смысл смотреть туда.
    Если С11 недоступен, смотреть в pthread_mutex_*, pthread_cond_*, ...

    Может стоит вынести флаг в параметры потока

    По-хорошему -- да, стоит. Это, однако, ортогонально к синхронизации доступа.

    while(!quit) {
            if(difftime(time(NULL), last_cycle) > 30) {
                last_cycle = time(NULL);
                // Тут мои грязные дела
            }
        }

    Вместо busy wait лучше использовать sleep или что-нибудь типа pthread_mutex_timedlock/pthread_cond_timedwait.

    Я бы оформил код этого примера так:
    #include <sys/time.h>
    #include <pthread.h>
    #include <stdbool.h>
    #include <string.h>
    #include <stdio.h>
    
    struct thread1 {
        pthread_mutex_t lock;
        pthread_cond_t cond;
        bool quit;
    };
    
    static void* thread_process(void *p) {
        struct thread1 *arg = p;
    
        for (;;) {
            bool quit;
    
            pthread_mutex_lock(&arg->lock);
            if (!arg->quit) {
                struct timeval now;
                struct timespec ts;
    
                gettimeofday(&now, NULL);
                ts.tv_sec = now.tv_sec + 30;
                ts.tv_nsec = now.tv_usec * 1000;
                pthread_cond_timedwait(&arg->cond, &arg->lock, &ts);
            }
            quit = arg->quit;
            pthread_mutex_unlock(&arg->lock);
            if (quit)
                return NULL;
    
            // Тут мои грязные дела
        }
        return NULL;
    }
    
    int main() {
        pthread_t th;
        struct thread1 arg = {
            .lock = PTHREAD_MUTEX_INITIALIZER,
            .cond = PTHREAD_COND_INITIALIZER,
            .quit = false,
        };
        pthread_create(&th, NULL, thread_process, &arg);
    
        char cmd[16];
        while(true) {
            scanf("%s", cmd);
            if(!strcmp(cmd, "quit")) {
                pthread_mutex_lock(&arg.lock);
                arg.quit = true;
                pthread_cond_broadcast(&arg.cond);
                pthread_mutex_unlock(&arg.lock);
                break;
            }
            // остальные команды
        }
    
        pthread_join(th, NULL);
        return 0;
    }
    Ответ написан
    1 комментарий
  • Как java поток выбирает ядро процессора?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    Как я понял, ядра имеют доступ только к своему L1 кэшу, а если поток будет исполняться на другом ядре, то он не увидит свои объекты, которые находятся в кэше другого ядра
    Я правильно мыслю?

    Нет. Все системы поддерживающие SMP имеют когерентный кеш. Т.е. если ядро обращается к данным, находящимся в L1 кеше другого ядра, то данные перемещаются в кеш запрашивающего ядра. См.
    Ответ написан
    Комментировать
  • Ошибка undefined reference to `pthread_create'. Как исправить?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    make -j1 -lpthread

    - вместо -lpthread лучше писать -pthread
    - опцию -pthread нужно передавать не make а gcc
    Ответ написан
    8 комментариев
  • Почему std::thread не работает без вызова std::cout?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    Не могу понять, почему у меня не отрабатывает std::thread без вызова cout? Как такое вообще возможно?

    А в ассемблер-то не заглянуть никак? Я вижу, что всё отрабатывает, что с cout, что без, что с -O0, что с -O2.
    Ответ написан
  • Как убрать IRQ системного таймера для потока приложения или ядра CPU?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    Есть есть поток, который добровольно не отдает управление ЦП и не должен.
    nonvoluntary_ctxt_switches: 68267288

    Этого недостаточно. Нужно чтобы кроме этого потока на данном CPU не было других. ctxt switch это переключение с одного потока на другой.

    Проблема в том, что системный таймер присылает прерывание LOC (Local timer interrupts) 1000 раз в секунду.

    Похоже, что у вас ядро с обычными тиками (не dyntick / tickless). Само таймерное прерывание, однако, не должно заметно влиять на производительность.

    Я бы не хотел манипулировать таймером вообще, или собирать ядро со специальными опциями

    Думаю, что вариантов без сборки ядра с опцией CONFIG_NO_HZ_FULL нет. Но и в этом случае, чтобы не было nonvoluntary ctxt switch на данном CPU должен быть единственный поток. См. https://www.kernel.org/doc/Documentation/timers/NO...
    Ответ написан
  • POSIX threads + usleep - почему не работает?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    usleep имеет код возврата и устанавливает errno в случае ошибки. Воспользуйтесь этим.
    Ответ написан
    Комментировать
  • Как один сетевой сокет обрабатывает много соединений?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    Выходит, что на стороне сервера все запросы маршрутизируются через один серверный сокет, забинденый на порту? Как происходит маршрутизация?

    Через серверный сокет проходят только запросы на установку соединения. После того как соединение установлено, на стороне сервера создаётся новый сокет, связывающий IP сервера на которым был принят запрос, порт сервера, IP клиента, отправившего запрос и порт клиента. Этого набора информации достаточно, чтобы определить, что пришедший пакет должен появиться в этом сокете, а при записи в сокет понять, куда отсылать пакет.
    Ответ написан
    3 комментария
  • Можно ли pThread поставить в состояние паузы из другого потока?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    В pthreads нет одной переносимой функции для того, что вы хотите сделать. Первую часть (поставить на паузу другой поток по его ID) можно реализовать с помощью сигналов, вторую (чтобы после создания поток был в состоянии паузы) -- с помощью примитивов синхронизации.
    Поиск по слову pthread_suspend выведет вас на возможные реализации.
    Ответ написан
  • Как вызвать C++ метод класса, callback из библиотеки на C?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    Насколько я помню, wxWidgets не умеет обрабатывать вызовы функций из других потоков.
    Скорее всего это не проблема взаимодействия C и C++. Для уверенности запустите приложение в gdb и покажите стектрейс в момент получения сигнала.
    Ответ написан
    Комментировать
  • Почему не работает распараллеливание потоков в gcc?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    for (i = 0; i < T; i++)
            for (j = 0; j < T; j++);

    На таком тестовом примере работу оптимизатора не увидеть никогда, потому что при -O0 оптимизатор не запускается, а при -О1,2,3 этот цикл будет выкинут целиком и заменён на i = T, j = T.
    Ответ написан
    1 комментарий
  • Как осуществить многопоточный запуск программ в linux на си?

    jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    //костыли для ожидания окончания работы процессов, чтобы не возиться с мьютексами и семафорами

    Достаточно вызвать pthread_join для каждого из запущенных потоков.

    fclose(f); //после того, как прочитали закрываем программу

    Должно быть pclose(f).

    id--; //минусуем счётчик потока

    Зря вы так, грязными руками в общую переменную.

    Из чего можно заключить: потоки и программы выполняются ПОСЛЕДОВАТЕЛЬНО

    Non sequitur. Но для полноты картины хотелось бы увидеть Makefile.
    Ответ написан
    1 комментарий