Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.52/131: Рейтинг темы: голосов - 131, средняя оценка - 4.52
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549

Архитектура: парсинг и выгрузка текстовиков

11.03.2020, 10:51. Показов 32490. Ответов 421

Студворк — интернет-сервис помощи студентам
начало было положено в ветке - Считать текстовые файлы из папки - там и возник вопрос об Архитектуре...
Цитата Сообщение от JeyCi Посмотреть сообщение
так и не собрала эти все объекты этого класса в group class...
вроде уже собрала...
осталось отображение создать (типа I_tbl_Show) и пронаследовать ? в разные классы пункта назначения (или на консоль, или в файл, или в БД, или допустим ещё в форму)... N.B. классы (пункты-назначения) делать не надо - эти View уже реализованы разработчиками того ПО, на котором сейчас идёт работа...
а) пока что можно просто прописать функции-члены класса; и по месту использовать, что надо при разработке - в файл или на консоль;
б) в перспективе для Release - реализовать и откомпилировать и выгрузку и в файл, и выгрузку в БД, и отражение в DataGrid...
===
!! Т.Е. если в Release захочется и выгрузку в текст, и в БД, и допустим ещё в форму (например с разных кнопок сделать) - тут уж лучше и писать, как положено, наследование??... -- к слову из прошлой ветки о:
Цитата Сообщение от JeyCi Посмотреть сообщение
полагаю тут Наследования никакого не пригодится?
... или как раз тут (при выборе направления выгрузки) его (наследование) делать??
===
Обоснование выбора уровня Абстракции (I_tbl_Show со всеми виртуальными функциями):
чтобы не дублировать код-сбора-для-выгрузки -- сделать class Table - и класс-интерфейс I_tbl_Show, в котором обозначить virtual-функции выгрузки... эти функции определить в др. классах - типа Interface (IwriteCSV, IwriteDB, IwriteDataGrid)...
p.s.
классы консоль, файл, бд, DataGrid - не создаём, т.к. эти пункты назначения уже присутствуют...
p.p.s.
вывести конечные интерфейсы с определёнными методами записи на кнопки...
===
ИЛИ то, что подчёркнуто чуть выше, стоит реализовать в одном классе Table, и здесь же задать все virtual функции ??
===
на скрине: синие - классы, зелёные - интерфейсы (в с++ по сути тоже классы)
птицами отмечены уже кое-как реализованные классы (2 птицы)
курсивные стрелки - отсутствие наследования


Добавлено через 7 минут
вобщем вопрос:
class Table и класс I_Tbl_Show - объединить или нет?

Добавлено через 10 минут
p.p.s.
чтобы избежать проблем Ромба и такого:
Неоднозначность при множественном наследовании
Цитата Сообщение от DrOffset Посмотреть сообщение
Тут нужно виртуальное наследование.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.03.2020, 10:51
Ответы с готовыми решениями:

Проверка двух текстовиков
Написать прогу на языке Си, проверяющую, совпадают ли тексты в двух файлах #include <stdio.h> #include <stdlib.h> ...

Access модуль объединения текстовиков
Добрый день. Очень нужен модуль access который будет объединять текстовые файлы с предложенной папки (каждый раз разные названия и...

Сделать скрипт для вывода текстов из текстовиков
Здравствуйте! Не могли бы помочь сделать скрипт для вывода текстов песен из текстовиков в папке. Расскажу подробней: есть папка с...

421
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.05.2020, 20:43
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от JeyCi Посмотреть сообщение
... но в thread_pool - этот yield лишний... т.к. сам pool, насколько понимаю, - очень активно ожидает, выполняя всё остальное в pool'e (все потоки, запущенные в работу)... вообще по количеству в queue - можно и такое количество thread'ов в pool'e открыть?.. циклом... потом также join'ить циклом, видимо... имхо
Если запускаешь задачу в пуле потоков, то не надо делать в ней никаких лишних циклов, тем более бесконечных. Просто выполнил какое-то действие, например загрузил файл с сайта, и вышел
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
28.05.2020, 21:00  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
файл с сайта
файлЫ...с разных линков...
===
вот, например, беру 1-ю попавшуюся реализацию:
Кликните здесь для просмотра всего текста
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//https://riptutorial.com/cplusplus/example/15806/create-a-simple-thread-pool
//Create a simple thread pool 
 
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <mutex>
#include <future>
#include <vector>
#include <deque>
 
struct tasks {
  // the mutex, condition variable and deque form a single
  // thread-safe triggered queue of tasks:
  std::mutex m;
  std::condition_variable v;
  // note that a packaged_task<void> can store a packaged_task<R>:
  std::deque<std::packaged_task<void()>> work;
 
  // this holds futures representing the worker threads being done:
  std::vector<std::future<void>> finished;
 
  // queue( lambda ) will enqueue the lambda into the tasks for the threads
  // to use.  A future of the type the lambda returns is given to let you get
  // the result out.
  template<class F, class R=std::result_of_t<F&()>>
  std::future<R> queue(F&& f) {
    // wrap the function object into a packaged task, splitting
    // execution from the return value:
    std::packaged_task<R()> p(std::forward<F>(f));
 
    auto r=p.get_future(); // get the return value before we hand off the task
    {
      std::unique_lock<std::mutex> l(m);
      work.emplace_back(std::move(p)); // store the task<R()> as a task<void()>
    }
    v.notify_one(); // wake a thread to work on the task
 
    return r; // return the future result of the task
  }
 
  // start N threads in the thread pool.
  void start(std::size_t N=1){
    for (std::size_t i = 0; i < N; ++i)
    {
      // each thread is a std::async running this->thread_task():
      finished.push_back(
        std::async(
          std::launch::async,
          [this]{ thread_task(); }
        )
      );
      //printf("Thread %d \r\n", i+1);          //<<<<<<<<<<<<<<<<<<<< output
    }
  }
  // abort() cancels all non-started tasks, and tells every working thread
  // stop running, and waits for them to finish up.
  void abort() {
    cancel_pending();
    finish();
  }
  // cancel_pending() merely cancels all non-started tasks:
  void cancel_pending() {
    std::unique_lock<std::mutex> l(m);
    work.clear();
  }
  // finish enques a "stop the thread" message for every thread, then waits for them:
  void finish() {
    {
      std::unique_lock<std::mutex> l(m);
      for(auto&&unused:finished){
        work.push_back({});
      }
    }
    v.notify_all();
    finished.clear();
  }
  ~tasks() {
    finish();
  }
private:
  // the work that a worker thread does:
  void thread_task() {
    while(true){
      // pop a task off the queue:
      std::packaged_task<void()> f;
      {
        // usual thread-safe queue code:
        std::unique_lock<std::mutex> l(m);
        if (work.empty()){
          v.wait(l,[&]{return !work.empty();});
        }
        f = std::move(work.front());
        work.pop_front();
      }
      // if the task is invalid, it means we are asked to abort:
      if (!f.valid()) return;
      // otherwise, run the task:
      f();
    }
  }
};
 
 
 
int main(int argc, const char *argv[])
{
/*tasks.queue( []{ return "hello world"s; } ) returns a std::future<std::string>, which when the tasks object gets around to running it is populated with hello world.
You create threads by running tasks.start(10) (which starts 10 threads).
The use of packaged_task<void()> is merely because there is no type-erased std::function equivalent that stores move-only types. Writing a custom one of those would probably be faster than using packaged_task<void()>.
*/
    tasks t;
    t.start(10);
       // ?????????????????/
    auto s=t.queue( []{ return "hello world"; } );
    std::cout << s.get() << std::endl;
    return 0;
}

- правильно ли я вас поняла и правильно ли применила в main() под спойлером ?? -- т.е. совсем без циклов... - 1 строка - у меня выполняется в 10-ти потоках (где я её потом join'ю? - хотя у меня packaged_task - наверно там и собирается всё), т.е. по сути ~ в 2 раза быстрее (т.к. 2 ядра) или даже ещё быстрее... ?

Добавлено через 4 минуты
и как мне добавить и запустить туда следующую фразу "Hello again"?..
- в порядке очерёдности в цикле?.. (ну допустим - это имитация подгрузки 2-х линков через пул потоков) - как должно выглядеть?.. и как расставить мьютексы в main'e? ... или они вроде уже в классе/структуре расставляются, похоже там в коде
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.05.2020, 21:08
Цитата Сообщение от JeyCi Посмотреть сообщение
и как мне добавить и запустить туда следующую фразу "Hello again"?..
- в порядке очерёдности в цикле?.. (ну допустим - это имитация подгрузки 2-х линков через пул потоков) - как должно выглядеть?
Что-то типа
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(int argc, const char *argv[])
{
    tasks t;
    t.start(10);
 
    std::vector<std::future<void>> futures;
    for (int i = 0; i < 100; ++i)
        futures.push_back(t.queue([i]
        {
            printf("Hello world #%d\n", i);
        }));
 
 
    for (auto &fut : futures)
        fut.get();
 
    return 0;
}
1
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
28.05.2020, 21:11  [ТС]
ок, завтра буду пробовать... зациклить на моё тз... если ускорится
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
28.05.2020, 21:11
Или то же самое
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main(int argc, const char *argv[])
{
    std::vector<std::future<void>> futures;
    for (int i = 0; i < 100; ++i)
        futures.push_back(std::async([i]
        {
            printf("Hello world #%d\n", i);
        }));
 
 
    for (auto &fut : futures)
        fut.get();
 
    return 0;
}
1
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
31.05.2020, 19:10  [ТС]
Потоки и процессы - правда Python, но разница между процессом и потоком очерчена достаточно - мой вывод: хоть с 1-го сокета и можно запустить только 1 процесс, но количество потоков в нём можно сделать любое...
с форума на U++ (пост 19 September 2017 10:12) чётко вырисовывается последовательность, что сначала Loop по Arr, внутри него Loop на свободный CPU Core... (когда они ещё разрабатывали свои библы для многопоточности)... т.е. по сути уровень_абстракции_Jobs с вложенным уровнем_абстракции_Workers рассматриваются... Scheduler'a там я вроде не заметила - хотя если это lightweight-вариант, как название той ветки, то может он и не нужен, раз вам код в полу_ручном варианте выбирает себе Worker'a... насколько поняла...
10 советов по многопоточному программированию на Java - 2 из которых (4 и 8) вы уже оставили в этой ветке...
!3-й и в связи с ним 9-й мне тоже показались очень заслуживающими внимания... в связи с этим моё заключение: Планирование Потоков - вообще очень важный этап в написании ТЗ - чтобы бездумным распараллеливанием не добавить тормозов... ... как и стремление к уменьшению областей синхронизации важно в коде (где потоки сливаются в один, условно, говоря, или использование атомарных счётчиков)...
также на заметку:
- join - "блокирует дальнейшее выполнение родительского потока, до тех пор, пока не будет завершён дочерний"
-detach - "неблокирующий метод"
= ну это на случай если всё-таки начну выделять потоки сама в рукописном классе... потому что все имеющиеся в std классы по потокам, думается мне, нуждаются в создании для них удобного wrapper'a, чтобы использовать без необходимости штамповать код дублируя его... в принципе thread_pool выше - один из вариантов приемлемой обёртки...
===
но ваш последний async-пример без использования pool_thread (не лезу читать std::future header) - тоже заинтересовал - вообще без thread_pool ?? - будет ли такая же скорость?
===
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
futures.push_back(std::async([i]
{/*do stuff*/}
мой stuff - здесь и можно сделать 2 шага: load url & save file... наверно, делить на 2 async операции бессмысленно... 2 эти операции вроде не имеют shared_variables (т.к. с разных url и в разные файлы запись)... единстренная shared_queue будет на входе и, возможно, её стоит выбросить в Producer... а Consumer асихронно вашим вариантом даже в самом main()'e можно сделать... ??
(ой не хочу усложнять ход мыслей - может, по простому сам цикл for Arr и есть условный Producer, а его внутренности условный Consumer?.. если суть Producer'a задавать атомарные единицы для итерирования)
===
Кликните здесь для просмотра всего текста
всё-таки шаблон Producer(writer to queue) - Consumer (reader from queue) - возможно стоит ещё рассмотреть ? - т.к. формирование Link'ов будет происходить из substrings... отменяется, т.к. это шаблон для работы с потоками, а мне всё время думается про мой массив линков... - всё-таки потоки - это новый уровень абстракции, не связанный с итерированием своих баранов... хоть atomic-обёртки для итератора и стоит не забывать при параллельной обработке данных... но сами птоки вступают в работу внутри каждого шага Loop по циклу данных...

===
вопрос, КАК расставить Семафоры, чтобы не колотить по чужому сайту остаётся (если запуск потоков осуществлять внутри Loop Arr) ...
- пример named_semaphore (на линк вышла отсюда)- наверно, пока обкатаю boost'овские (не WinAPI) - как-то проще кажется (более высокоуровнево в boost'e, чем в std)... если пойму как и стоит ли... всё-таки подбор библиотеки - занятие не из лёгких, когда свои ещё не пишешь...
===
Методика разработки многопоточных приложений: принципы и практическая реализация -- всё-таки с отладкой потоков и отловом исключений я пока на вы
P.S.
Аппаратная реализация - вот бы её хватало...
что-то замечаю, что даже vba-код сам по себе уже стал как-то подгружать конкурентно, а не как раннее - последовательно... сама удивляюсь ему
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
31.05.2020, 19:16
Цитата Сообщение от JeyCi Посмотреть сообщение
но ваш последний async-пример без использования pool_thread (не лезу читать std::future header) - тоже заинтересовал - вообще без thread_pool ?? - будет ли такая же скорость?
std::async запускает задачу в пуле потоков. Не знаю, что такое thread_pool, но, подозреваю, std::async отработает намного лучше.
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
31.05.2020, 19:21  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
std::async запускает задачу в пуле потоков
вот тоже по вашему коду подумала, что где-то за плечами async - сам пул потоков уже стоит... спасибо, что подтвердили мои предположения!
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
31.05.2020, 19:34
Цитата Сообщение от JeyCi Посмотреть сообщение
вопрос, КАК расставить Семафоры, чтобы не колотить по чужому сайту остаётся (если запуск потоков осуществлять внутри Loop Arr) ...
Привязываешь семафор к конкретному сайту, например при помощи std::map, и блокируешь его перед отправкой запроса
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
01.06.2020, 22:37  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Привязываешь семафор к конкретному сайту, например при помощи std::map
- там все линки с одного сайта...
?? если через std::map -- то, полагаю, как-то так:
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
#include <iostream>
#include <vector>
#include <future>
 
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
 
#include <fcntl.h>
 
int main(int argc, const char *argv[])
{
    std::vector<std::future<void>> futures;
    sem_t semaphore1;
    
    sem_init(&semaphore1, 0, 0);
        
    for (int i = 0; i < 100; ++i) { 
        futures.push_back(std::async([&]
        {            
            printf("Hello world #%d\n", i); 
            //signaled_state - unlock - отпускает i, работает далее асинхронно...
            //Функция sem_post() безопасна для асинхронных сигналов: её можно использовать внутри обработчика сигналов. 
            sem_post(&semaphore1);  //разблокирует семафор; Функция sem_post() увеличивает (разблокирует) семафор, на который указывает sem. Если значение семафора после этого становится больше нуля, то другой процесс или нить заблокированная в вызове sem_wait(3), проснётся и заблокирует семафор. 
            printf("job takes place here: loading & saving url from std::map at key=i\r\n");
        }));  
        //блокирует семафор     
        sem_wait(&semaphore1);          //waiting_state  - lock => can use i safely - as it is shared_value    
    }
    sem_destroy(&semaphore1);
 
    for (auto &fut : futures)
        fut.get();
 
    return 0;
}
... или, чтобы не гнать очень быстро, ещё как-то sleep расставить стоит?.. - или того, что написала достаточно?...
p.s.
вообще семафоры поуниверсальнее, чем condition_variables. т.к. последние использоваться начали для win7... спасибо за совет...
p.p.s.
и ещё вопрос: может стоит семафор включать-выключать на, например, 10 линков - so named многоместный турникет ?.. хотя для данного случая (инкрементирование i) - это не пройдёт ? (т.к. эти 10 между собой устроят race condition)...
===
вобщем правильно ли моё видение вашего совета по коду ? или можно быстрее (т.е. уменьшить количество мест синхронизации или использовать иные примитивы синхронизации)... хотя по совсем atomic - выдержку видела - видимо, не совсем comme ils faut
Disadvantages
● atomic operations may drive you crazy
● absence of easy understandable manual
● atomic operations are more expensive than their
non-atomic counterparts
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
01.06.2020, 22:43
Цитата Сообщение от JeyCi Посмотреть сообщение
... или, чтобы не гнать очень быстро, ещё как-то sleep расставить стоит?.. - или того, что написала достаточно?...
Какие там условия - сколько можно отправлять запросов и за какое время?

Добавлено через 1 минуту
Цитата Сообщение от JeyCi Посмотреть сообщение
//блокирует семафор    
        sem_wait(&semaphore1);          //waiting_state  - lock => can use i safely - as it is shared_value
Семафор надо блокировать в функции потока - в async, а не снаружи
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
01.06.2020, 23:17  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Семафор надо блокировать в функции потока - в async
sem_post(&semaphore1) и sem_wait(&semaphore1) местами поменять... а так локация в коде правильная?..
я i рассматривала, как shared_value - вот и расставила до обращения к нему и после обращения к нему...
всё-таки каждое i в поток
тут опять, видимо, перевернуть взгляд надо с итератора на потоки... вечно меня итератор смущает...
(мне вообще о нём надо забыть в этом тз, когда дело доходит до потоков)


Добавлено через 4 минуты
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Какие там условия - сколько можно отправлять запросов и за какое время?
нееет... этого я пока не знаю... я ещё класс, формирующий линки не дописала, чтобы проверить... sorry

Добавлено через 4 минуты
Цитата Сообщение от JeyCi Посмотреть сообщение
местами поменять... а так локация в коде правильная?..
вобщем, наверно всё в async - завтра переделаю... всё равно хочется sem_wait до строки, оперирующей i (строка 21), использовать, а sem_post после
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
02.06.2020, 10:47  [ТС]
Цитата Сообщение от JeyCi Посмотреть сообщение
loading & saving url from std::map at key=i
и тут всё-таки 2 потока, наверно, надо выделить - работающих последовательно др.з за др. ... это надо каждый шаг завернуть в async?.. (в рамках одного Loop i)... что-то сильно много точек синхронизации (блокирования) начинают наворачиваться..

Добавлено через 10 минут
===
я прбовала сделать такой вариант - для чтения файлов:
C++
1
2
3
4
5
6
7
8
9
10
11
12
    auto a = Async([=,&vec]() -> String {
        String s;
        s="";
        for (auto&  row:vec){ 
                Upp::String fileData = fetchDataFromFile(row);
                s=s+"\r\n"+fileData;
            }
        //LOG(s);
        return s;
        });
        
    a.Get();
с такими функциями
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
Upp::Vector <Upp::String> myGetFld(Upp::String p)
{
    Upp::Vector <Upp::String> vec;
       
    for(Upp::FindFile ff(Upp::AppendFileName(p, "*.*")); ff; ff.Next()) 
    {
        vec.push_back(Upp::AppendFileName(p,ff.GetName()));
    }     
    return vec;
}
 
Upp::String fetchDataFromFile(Upp::String recvdData)
{
    using namespace std; 
        
    //Do stuff like fetching Data File
    FileIn in(recvdData);
    if(in) {
        String data;
        while(!in.IsEof()) {
            String line = in.GetLine();
            data=data+line;
        }
        in.Close();
        return data;
    }
    else {
        in.Close();
        return ("Failed to open the file");
    }
}

- не знаю, насколько такой подход может быть логичен? - тут вроде вообще без синхронизации - не будет ли race condition?.. хотя вроде не должно быть - т.к. просто загоняем в async всё, что надо сделать, а потом типа, наверно, коллбэком достаём из фьюча?.. я пока механику асинхронности вижу так...
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.06.2020, 15:30
Цитата Сообщение от JeyCi Посмотреть сообщение
sem_post(&semaphore1) и sem_wait(&semaphore1) местами поменять... а так локация в коде правильная?..
sem_wait вроде блокирует семафор, sem_post - разблокирует. В таком порядке они и должны вызываться. Раньше у тебя тоже неправильно было сделано
Кроме того, эта пара функций должна вызываться в одном потоке.
1
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
02.06.2020, 20:39  [ТС]
пару линков всё-таки оставлю:
writer-reader, aka producer-consumer по сути, вероятно... (чтобы знать как выглядит)
и winAPI семафоры...
в std - только в c++v.20 counting_semaphore появляется - если всё-таки "многоместный турникет" выбрать...
===
Добавлено через 12 минут
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Кроме того, эта пара функций должна вызываться в одном потоке.
т.е. надо выделить потоки!?..
по типу такого
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
int main()
{
 
    std::cout << "Main thread id=" << std::this_thread::get_id() << "\n";
    auto asyncDefault = std::async([]()
    {
        std::cout << "Async default, Threadid=" <<
            std::this_thread::get_id() << "\n";
    });
 
    auto asyncDeffered= std::async(std::launch::deferred,
        [](const std::string& str)
    {
        std::cout << "Async deffer, Threadid="
            << std::this_thread::get_id() << "," << str << "\n";
    }, std::string("end string"));
 
    auto asyncDeffered2  = std::async(std::launch::deferred, []()
    {
        std::cout << "Async deffer2, Threadid="
            << std::this_thread::get_id() << "\n";
    });
 
    auto trueAsync = std::async(std::launch::async, []()
    {
        std::cout << "True async, Threadid="
            << std::this_thread::get_id() << "\n";
    });
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "Sleep ended\n";
    asyncDefault.get();
    asyncDeffered.get();
    trueAsync.get();
}

потом в них применять эту пару, чтобы задействовать семафор "до" и "после" Критической Секции (вопрос: где она??)...
и итератор, как shared_value, как мне показалось ранее, тут не причём... ?
но всё равно как-то визуализировать потоки сложно - если за async'ом стоит пул потоков... ?.. как туда впихнуть wait-notify семафора для каждого потока... - в саму лямбду...
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Семафор надо блокировать в функции потока - в async, а не снаружи
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.06.2020, 20:47
Цитата Сообщение от JeyCi Посмотреть сообщение
т.е. надо выделить потоки!..
В смысле? Функция, которую ты передаёшь в std::async и будет выполнена в "одном потоке", в ней нужно вызвать sem_wait/sem_post

Добавлено через 3 минуты
Я что-то потерял нить, что ты вообще пытаешься сделать. Подозреваю, там задача довольно простая
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
02.06.2020, 22:01  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
В смысле?
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Пока один поток ждёт эту загрузку, другие будут работать.
ну, то, что 1 сокет обслуживает 1 процесс - это разобрались... но запустить циклом линки на подгрузку в одном потоке... и отдавать их на запись в файлы в др. потоке, чтобы не блокировать, пока записывается... или это я уже совсем расчленяю процесс на лишнее количество потоков?..
вобщем вопрос: async запускать на каждую итерацию по циклу или, как я пробовала с подгрузкой из файлов - сам цикл по линкам (весь) разместить в asynce?.. и там же как-то пропускать каждый шаг цикла через семафор... опять же только загрузку или на время сохранения в файл семафор тоже оставлять в заблокированном виде (wait) ?
чтобы не членить на процессы для того, чтобы они потом стояли в очередь на семафор?.. (наверно, в этом вопрос - сократить этапы синхронизации)

Добавлено через 7 минут
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Подозреваю, там задача довольно простая
я тоже только подозреваю... беру список линков - (наверно переделаю в map - к ним пути файлов, куда сохраняться) - гружу асинхронно по возможности не разрывая связь - хотя запросы GET всё-таки отдельные объекты на каждый линк... но в любом случае - ещё потом и записать IO в файлы (каждый линк в свой файл)... и чтобы в максимально короткое время это сделать... вот и думаю, как разбросать по потокам...
ИЛИ
каждый линк в отдельный поток запускать (т.е. своя async для каждого)?.. как лучше?
... все линки к одному сайту - разные urls

Добавлено через 4 минуты
и нужен ли мне тут семафор

Добавлено через 2 минуты
p.s.
это кстати жёлтое облако на скрине #1 ветки...


Добавлено через 18 минут
===
кстати здесь
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Мьютексом надо блокировать только те данные, которые ты изменяешь, а не всё подряд.
в моём случае, может, синхронизация вообще не нужна?
я только счётчик по циклу меняю... но если цикл положить в async - то там свои дела - синхронизировать не надо... имхо
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.06.2020, 22:04
Цитата Сообщение от JeyCi Посмотреть сообщение
я тоже только подозреваю... беру список линков - (наверно переделаю в map - к ним пути файлов, куда сохраняться) - гружу асинхронно по возможности не разрывая связь - хотя запросы GET всё-таки отдельные объекты на каждый линк... но в любом случае - ещё потом и записать IO в файлы (каждый линк в свой файл)... и чтобы в максимально короткое время это сделать... вот и думаю, как разбросать по потокам...
Я тебе вроде показывал свою реализацию примитивного пула потоков.
По сути там описан асинхронный обработчик задач. Эти задачи кладутся в очередь, потом потоки забирают их оттуда и выполняют.
Каждая задача - это твой линк, который нужно загрузить/сохранить. Так как сайт у тебя один, то для того, чтобы ограничить количество коннектов к нему, достаточно будет просто запустить ограниченное количество потоков-обработчиков (оно там параметром задаётся)
1
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
02.06.2020, 22:13  [ТС]
p.s.
но Single lane bridge Synchronization using semaphores лучше погуглить... (если сайт не пропустит все линки быстро)

Добавлено через 4 минуты
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
достаточно будет просто запустить ограниченное количество потоков-обработчиков (оно там параметром задаётся)
вот спасибо - ещё просто не успела толком ознакомиться - много линков открыто, по-тиху разгребаю - и теорию, и коды пока мельком... прочитаю внимательно, попробую применить... thanks
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
03.06.2020, 09:03  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Эти задачи кладутся в очередь
запомню на всю жизнь
Concurrency != parallelism
§ Concurrency is doing multiple tasks at a time
§ Parallelism is executing multiple CPU instructions simultaneously
т.е.
Очередь конкурирует за процессорное время...
Многоядерность - выгодна для математических вычислений (если в рамках входящих в функцию параметров выделяются atomic элементы и/или шаги обработки)...
p.s.
и много интересных примеров - правда на header'e от Stanford University... но header и свой когда-нибудь можно написать... а задачу о ticketSellers - о том, какой поток продал сколько ticket'ов - для практики полезно хотя бы визуализировать те потоки... как и др задач...
p.p.s.
после Планирования Потоков см. Менеджмент потоков (с пониманием основных проблем - race conditions, deadlocks, greedy for resources etc)... и цикл статей Кенни Керра полезен в этом контексте...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.06.2020, 09:03

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

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

Ошибка "в указанном dsn архитектура драйвера и архитектура приложения"
Вот такая ошибка при нажатии на кнопку &quot;Проверить соединение&quot; Я прочитал, что это возможно из за того, что моя система 64, а...

Архитектура бд
Я начинающий php-разраб. Пишу свой проект для своего города. Но встал вопрос о архитектуре. Пользователь создает свою страницу с...

Архитектура БД
Доброго времени суток.Задание написать АИС Учёт абонентов телефонной сети предприятия. Краткое описание предметной области: В состав...


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

Или воспользуйтесь поиском по форуму:
140
Ответ Создать тему
Новые блоги и статьи
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения. https:/ / habr. com/ ru/ sandbox/ 295048/ начало и оглавление - Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование. . .
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0) Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона Уважаемые коллеги! В продолжение. . .
Грибы - это женщины, деревья - это мужчины. Анти инь янь для союза мужчины и женщины.
anaschu 18.07.2026
ГЛАВНЫЙ НАУЧНО-ФИЛОСОФСКИЙ ВЫВОД: Сексуально-Репродуктивный Капитализм против Государства Моногамии Коллеги, мы вышли на финишную прямую 20-мерного ОДУ-моделирования вековой сукцессии (ветка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru