На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> gcc - установка и настройка
    Всем привет!
    У меня тут подработка наклюнулась, в одну контору на C++.
    Проблема даже не в том, что именно ++ я не знаю (там стажировка на лето, ещё 10 раз выучу). Проблема в том, что нужно сразу сдать тестовое задание. И самое сложное из задания - это чтобы оно должно компилироваться cmake или make с gcc под линукс.
    До сего дня я жил в уверенности, что за мкадом жизни нет есть только два компилятора Visual Studio и Watcom. Которыми и пользовался время от времени. А тут сразу gcc, да еще под линукс, который я и в глаза не видел.

    Собственно вопрос.
    Как нормально установить gcc под винду, в IDE Visual Code Studio. Просто по инету шариться - это уйму времени потеряешь, пока найдешь верный вариант. И как сделать чтобы программы (а их две, многопоточные и взаимодействующие между собой) компилировались с помощью make и cmake?

    Задание я и сам сделаю, но остаются неясные моменты (я конечно их могу загуглить, но буду очень признателен за сэкономленное время):
    1) потоки в C++ создаются через std::thread?
    2) Потоком можно сделать класс? Точнее экземпляр класса? Есть какие то тонкости?
    3) какие стандартные средства есть для синхронизации доступа к данным между потоками? Просто я в винде всю жизнь использовал мьютексы и семафоры, а вот что есть в ++ даже не представляю.
    4) основная проблема: как передать данные из одной программы в другую, чтобы работало и на винде и на линуксе?

    Я не пишу что за задание, поскольку хочу сделать сам. Но если кому интересно, буду признателен за помощь в описании классов. Просто на мой взгляд задание настолько простое, что ООП там совершенно не нужно. Но в задании чётко сказано:
    Цитата
    Не обязательно все размещать в одном классе. Может быть разработана иерархия классов. Чем более функционален интерфейс класса, тем лучше.
    И для меня это действительно головная боль :)
      А может начать с чего по "проще". Например, установить под Windows Linux Ubuntu и уже с ним получить свой gcc. Или вообще установить Linux отдельно на виртуальную машину и из под нее уже писать программы (Visual Studio Code есть и на Linux и она по умолчанию находит g++/gcc).

      Если все же надо установить на Windows тогда смотрите в сторону MinGW (в комплекте содержит MSYS и g++/gcc).

      Добавлено
      Цитата Eretic @
      И для меня это действительно головная боль

      Если хотите делать самостоятельно, то разобраться в наследовании как раз будет полезным самостоятельным занятием.
        Цитата macomics @
        А может начать с чего по "проще". Например, установить под Windows Linux Ubuntu и уже с ним получить свой gcc. Или вообще установить Linux отдельно на виртуальную машину и из под нее уже писать программы (Visual Studio Code есть и на Linux и она по умолчанию находит g++/gcc).

        А вот это я бы не рекомендовал делать! Бритва Оккама однако. ;) Если нужно разбираться с gcc, то можно и нужно это делать напрямую, а не через разборки с Линупсом.

        Цитата Eretic @
        Собственно вопрос.
        Как нормально установить gcc под винду, в IDE Visual Code Studio. Просто по инету шариться - это уйму времени потеряешь, пока найдешь верный вариант. И как сделать чтобы программы (а их две, многопоточные и взаимодействующие между собой) компилировались с помощью make и cmake?

        Рекомендую почитать мою статью из раздела C/C++ FAQ "Его величество MSYS2". Получение GCC "из коробки". Ну и в дополнение полностью настроенную IDE OtCreator. Так что только останется разыскать инфу по настройке и подключению к VS Code компиляторов и отладчиков.
          В задании никакой VS Code не фигурирует. Полагаю, работодатель хочет увидеть от соискателя умение получить "Здравствуй, мир!" при помощи подручного текстового редактора и командной строки.
          Цитата Majestio @
          Бритва Оккама однако. Если нужно разбираться с gcc, то можно и нужно это делать напрямую, а не через разборки с Линупсом.
          Вообще-то нужно именно под линукс и бритва просится по отношению ко всяким MSYS2 и VS.
            Цитата Majestio @
            А вот это я бы не рекомендовал делать! Бритва Оккама однако.

            И где вы это тут увидели. GNU Compiller Collection разрабатывалась как раз под Unix системы и начинать с ней работать как раз таки проще на Linux, а не на Windows. Тем более, если проект
            Цитата Eretic @
            И самое сложное из задания - это чтобы оно должно компилироваться cmake или make с gcc под линукс.
            , тогда сам бог велел поставить Linux и проверять работоспособность на нем.
              1. Да.
              2. Нет. Класс – это тип, а поток – это последовательность действий. Это совершенно разные сущности. Даже объект – экземпляр класса – это отдельно взятый комплект атрибутов, характеризующих класс, которые можно опрашивать и менять, но последовательность действий им всё равно никакой не приписывается. Можно потоком сделать какой-то метод класса, если очень хочется.
              3. Та мьютексы и семафоры и есть. Нужно только с разбегу не перепутать std::mutex с виндовыми Mutex, который std::recursive_mutex. А тот, что std::mutex, то виндовый Semaphore со счётчиком 2. Ещё вот недавно появились полноценные std::counting_semaphore и std::binary_semaphore, но я их ещё не пробовал.
              4. Тут стандартного решения нет. Стандарт не описывает взаимодействие программных комплексов, он описывает конкретную программу.
              Сообщение отредактировано: Qraizer -
                Цитата Dushevny @
                Вообще-то нужно именно под линукс

                Читаем внимательнее!
                Цитата Eretic @
                оно должно компилироваться cmake или make с gcc под линукс

                После естественной установки MSYS2 под винду - мы получаем тестовый полигон с Linux-подобным окружением сразу. Поэтому не нужно переворачивать мое высказывание с ног на голову. Нужно чтобы компилировалось под Линь, пожалуйте. Но нигде не было сказано, что компиляция должна быть именно на живой, установленный на железо Линупс.
                  P.S. "Самый кроссплатформенный" обмен данными между приложениями – сокеты на 127.0.0.1. Будет работать везде. Правда, виндовые сокеты чуток отличаются от берклиевых, но там несложно найти общее поле, если нужен просто обмен данными.
                  Сообщение отредактировано: Qraizer -
                    Цитата macomics @
                    как раз таки проще на Linux, а не на Windows

                    Т.е. топикстартеру нужно сперва Линупс "выучить", а потом только "gcc"? Не согласен.
                      Цитата Majestio @
                      Т.е. топикстартеру нужно сперва Линупс "выучить", а потом только "gcc"? Не согласен.

                      Выучить линукс? Это как? Как стихотворение, наизусть выучить исходники? У Linux такой же интуитивный интерфейс как у Windows и, уже давно, куда удобнее чем на Windows.
                        Спасибо всем ответившим!
                        Сразу скажу - установка линукса у меня пока невозможна, чисто по техническим причинам. Комп никак не соберу (жду комплектуху с Китая), а ноут прочно завязан на винду (есть специфические приложения, нужные по работе).

                        Цитата Majestio @
                        Рекомендую почитать мою статью из раздела C/C++ FAQ "Его величество MSYS2".

                        Спасибо, сейчас гляну.
                        VSCode я упомянул просто как бесплатную IDE, в которой учу шарп и питон. Мне в принципе несущественно из под чего работать, могу и из блокнота. Главное чтобы makefile как-то создать для проекта.

                        Цитата Dushevny @
                        Полагаю, работодатель хочет увидеть от соискателя умение получить "Здравствуй, мир!" при помощи подручного текстового редактора и командной строки.

                        В задании сказано, что они будут компилировать под линуксом, насколько я понял. И чтобы компиляция была простым запуском make или cmake. И если в "приличных" компиляторах присутствуют IDE, генерирующие makefile, то на счет gcc я что-то не уверен, у него ведь нет своей IDE? Тогда как происходит процесс создания makefile?

                        Цитата Qraizer @
                        Нет. Класс – это тип, а поток – это последовательность действий. Это совершенно разные сущности. Даже объект – экземпляр класса – это отдельно взятый комплект атрибутов, характеризующих класс, которые можно опрашивать и менять, но последовательность действий им всё равно никакой не приписывается. Можно потоком сделать какой-то метод класса, если очень хочется.

                        Ясно. Значит проще не париться с классами и реализовать как и в винде - простой функцией. А там может и придумаю как классы прикрутить :)

                        Цитата Qraizer @
                        Та мьютексы и семафоры и есть. Нужно только с разбегу не перепутать std::mutex с виндовыми Mutex, который std::recursive_mutex. А тот, что std::mutex, то виндовый Semaphore со счётчиком 2. Ещё вот недавно появились полноценные std::counting_semaphore и std::binary_semaphore, но я их ещё не пробовал.

                        Спасибо. Это всё упрощает.

                        Цитата Qraizer @
                        P.S. "Самый кроссплатформенный" обмен данными между приложениями – сокеты на 127.0.0.1. Будет работать везде.

                        Отличная идея! Значит завтра поищу как совместить. На крайняк сделаю через #define (я студент, мне можно :) )
                          Цитата macomics @
                          У Linux такой же интуитивный интерфейс как у Windows и, уже давно, куда удобнее чем на Windows.

                          :facepalm: свои - шел, пакетные менеджеры, особенности ФС и пр. пр. Все это ты предлагаешь изучить человеку, который все время просидел на винде. Лишь для того, чтобы разобраться с gcc. Не на одном GUI свет клином сошёлся же.

                          Добавлено
                          Цитата Eretic @
                          то на счет gcc я что-то не уверен, у него ведь нет своей IDE? Тогда как происходит процесс создания makefile?

                          Касаемо QtCreator'а - там подключаются различные системы сборки, типа qmake, cmake, qbs. Вот они, в качестве промежуточного этапа, могут создавать make-файлы. На счет qmake - это 100%, остальные не пользовал, не могу утверждать.
                            Цитата Majestio @
                            шел, пакетные менеджеры, особенности ФС и пр. пр.

                            Это так и так понадобится по заданию.

                            Цитата Majestio @
                            Все это ты предлагаешь изучить человеку, который все время просидел на винде, лишь для того, чтобы разобраться с gcc.

                            Если он будет использовать glibc, тогда все это не понадобится до поры до времени. Но, если программа должна работать под linux, то без изучения всех этих особенностей не обойтись. Адаптировать код под несколько операционных систем без изучения их особенностей не получится. И для кросс-платформенного проекта придется все это освоить.

                            В любом случае начинать осваивать gcc на linux проще чем на windows. На windows отсутствует man pages (как аналог MSDN и справки по glibc) и другие ресурсы с информацией. Её приведётся откапывать в интернете. А в те же оконные менеджеры (KDE, Gnome, Mate etc) уже встроены приложения, которые позволяют удобно искать страницы man pages даже не зная их названия, а по их содержимому.

                            Добавлено
                            Цитата Eretic @
                            а ноут прочно завязан на винду (есть специфические приложения, нужные по работе).

                            В этом случае можно поставить виртуальную машину и на нее поставить linux. Я об этом способе написал еще в #3.

                            Добавлено
                            Для виртуальной машины с Linux вам достаточно: 1.5 GHz процессора (одноядерного), 2048 + 64 Мб RAM и 20 Гб на жестком диске
                              Цитата macomics @
                              Если он будет использовать glibc, тогда все это не понадобится до поры до времени. Но, если программа должна работать под linux, то без изучения всех этих особенностей не обойтись. Адаптировать код под несколько операционных систем без изучения их особенностей не получится. И для кросс-платформенного проекта придется все это освоить.

                              В любом случае начинать осваивать gcc на linux проще чем на windows. На windows отсутствует man pages (как аналог MSDN и справки по glibc) и другие ресурсы с информацией. Её приведётся откапывать в интернете. А в те же оконные менеджеры (KDE, Gnome, Mate etc) уже встроены приложения, которые позволяют удобно искать страницы man pages даже не зная их названия, а по их содержимому.

                              Ему нужно пока лишь выполнить тестовое задание. Зачем сейчас всё усложнять? Разборки с Линуксом - это отдельная тема. Полезная? Несомненно. Но это совсем другая история... Заканчиваю - решать топикстартеру.
                                Цитата Majestio @
                                Зачем сейчас всё усложнять?

                                Затем, что по заданию она должна компилироваться на linux. И вот тут косяк, если из-за как-то не учтенной особенности linux, не выученной своевременно, программа просто не сможет откомпилироваться.

                                Вот элементарный пример. Для взаимодействия предложили использовать socket. Но на Windows для работы с socket надо использовать WSAStartup и WSACleanup, которых нету в linux. Т.е. с виду работоспособный код для Windows под linux просто выдаст ошибку отсутствия функций.
                                Сообщение отредактировано: macomics -
                                  С MSYS2, по мере установки, возникают проблемы:
                                  Цитата
                                  error: failed retrieving file 'python-3.11.7-1-x86_64.pkg.tar.zst' from mirror.msys2.org : Failed to connect to fastmirror.pp.ua port 443 after 10011 ms: Timeout was reached
                                  error: failed retrieving file 'cppdap-1.58.0a-3-x86_64.pkg.tar.zst' from mirror.msys2.org : Connection timeout after 10000 ms
                                  error: failed retrieving file 'libarchive-3.7.2-1-x86_64.pkg.tar.zst' from mirror.msys2.org : Connection timeout after 10000 ms
                                  warning: too many errors from mirror.msys2.org, skipping for the remainder of this transaction
                                  error: failed retrieving file 'librhash-1.4.3-1-x86_64.pkg.tar.zst' from mirror.msys2.org : Connection timeout after 10000 ms

                                  Ни один пакет не установился без подобных ошибок, начиная с самой первой команды: pacman -Suy
                                  Как быть? Я в целом знаю как через VPN гулять по всяким ChatGPT, но вот обманывать установщики, которые напрямую лезут в инет - нас не учили :(

                                  Добавлено
                                  Цитата macomics @
                                  Затем, что по заданию она должна компилироваться на linux. И вот тут косяк, если из-за как-то не учтенной особенности linux, не выученной своевременно, программа просто не сможет откомпилироваться.

                                  Мне не настолько нужна эта практика, чтобы ради неё делать слишком серьезные телодвижения :) Мой ноут у меня детишки изъяли, а мне взамен подарили это чудо, на 1,1 ГГц :) Для работы хватает, а вот что серьёзнее - уже нет. Поэтому и собираю комп, 8-ми ядерник, с 32 Гб памяти. У нас ближе к весне в программе обучения будет линукс, в частности его установка на виртуалку. Вот тогда и познакомлюсь с ним поближе, тем более как раз комп будет готов.
                                  Пока же попробую в винде. Не получится - да и фиг с ней, к лету еще конторы найдутся для практики.
                                    Цитата Eretic @
                                    Ни один пакет не установился без подобных ошибок, начиная с самой первой команды: pacman -Suy
                                    Как быть? Я в целом знаю как через VPN гулять по всяким ChatGPT, но вот обманывать установщики, которые напрямую лезут в инет - нас не учили

                                    Явно с инетом большие проблемы :-? Я еженедельно обновляю свой MSYS2. Он вытягивает по 300-700Mb без единой ошибки. Что посоветовать в таком случае - затрудняюсь. Может другой канал в Инет поискать, провайдера сменить ... Не знаю.

                                    Добавлено
                                    Цитата macomics @
                                    Вот элементарный пример. Для взаимодействия предложили использовать socket. Но на Windows для работы с socket надо использовать WSAStartup и WSACleanup, которых нету в linux. Т.е. с виду работоспособный код для Windows под linux просто выдаст ошибку отсутствия функций.

                                    Лучше проблемы решать по мере их появления. Этого в задании пока не было. Зачем заранее тратить время на то, чего не просили. Вопрос риторический.
                                      Цитата Majestio @
                                      Явно с инетом большие проблемы

                                      Мне кажется дело в другом:
                                      Failed to connect to fastmirror.pp.ua port 443
                                        Тогда попробуйте способ с виртуальной машиной. Не знаю как долго вы будете скачивать 3-5 Гб образ linux, но обычно он успешно устанавливается за 20 минут на виртуальную машину. Будет у вас на Windows окошко с монитором виртуальной машины и там будете работать (при желании сможете сделать его на весь экран). Приложения на том же Ubuntu ставятся через магазин приложений - бесплатно. Там и найдете VS Code.
                                          Цитата Eretic @
                                          Ни один пакет не установился без подобных ошибок, начиная с самой первой команды: pacman -Suy
                                          Как быть? Я в целом знаю как через VPN гулять по всяким ChatGPT, но вот обманывать установщики, которые напрямую лезут в инет - нас не учили

                                          Вдогонку. MSYS2 использует пакетный менеджер от ArchLinux. Глянь эту статью. Можно попробовать поиграться с зеркалами. И да ... все варианты редактирования а-ля /etc/pacman.d/mirrorlist можно редактировать средствами винды (не обязательно из терминала MSYS2). Нужно только соблюдать правильные юниксовые переводы строк.

                                          Добавлено
                                          Цитата Eretic @
                                          Мне кажется дело в другом:
                                          Failed to connect to fastmirror.pp.ua port 443

                                          В таких случаях должны перебираться резервные хранилища :-?

                                          Добавлено
                                          Если совсем не получается - поставь PlanetVPN на время установки. Он бесплатный без выбора сервера (что дадут). Потом удалишь или выключишь за ненадобностью. И да, самой первой командой в терминале MSYS2 сделай полное обновление:
                                          ExpandedWrap disabled
                                            pacman -Syyuu
                                            С VPN поначалу тоже ошибки пошли:
                                            ExpandedWrap disabled
                                              pacman -Syyuu
                                              :: Synchronizing package databases...
                                               clangarm64                      429.2 KiB   391 KiB/s 00:01 [###############################] 100%
                                               mingw32                         312.8 KiB   314 KiB/s 00:01 [###############################] 100%
                                               mingw64                         476.9 KiB   431 KiB/s 00:01 [###############################] 100%
                                               ucrt64                          485.4 KiB   459 KiB/s 00:01 [###############################] 100%
                                               clang32                         306.2 KiB   295 KiB/s 00:01 [###############################] 100%
                                               clang64                         476.5 KiB  1876 KiB/s 00:00 [###############################] 100%
                                               msys                            484.4 KiB  1357 KiB/s 00:00 [###############################] 100%
                                              error: failed retrieving file 'clangarm64.db' from mirror.msys2.org : Resolving timed out after 10005 milliseconds
                                              error: failed retrieving file 'mingw32.db' from mirror.msys2.org : Connection time-out
                                              error: failed retrieving file 'mingw64.db' from mirror.msys2.org : Connection time-out
                                              warning: too many errors from mirror.msys2.org, skipping for the remainder of this transaction
                                              error: failed retrieving file 'ucrt64.db' from mirror.msys2.org : Connection time-out
                                              error: failed retrieving file 'clang32.db' from mirror.msys2.org : Connection time-out
                                              :: Starting core system upgrade...
                                               there is nothing to do
                                              :: Starting full system upgrade...
                                               there is nothing to do

                                            Правда уже без UA. И через минуту наконец-то заработало :)
                                            В процессе только одна ошибка и всплыла:
                                            ExpandedWrap disabled
                                              $ pacman -S --noconfirm mingw-w64-i686-qt5 mingw-w64-i686-qt5-static mingw-w64-i686-qt5-doc
                                              error: target not found: mingw-w64-i686-qt5
                                              error: target not found: mingw-w64-i686-qt5-doc

                                            Надеюсь не критично.
                                            Ну всё, завтра настрою и опробую.
                                              Цитата Eretic @
                                              Надеюсь не критично.
                                              Ну всё, завтра настрою и опробую.

                                              Гуд! Последнюю команду можно (и нужно) запускать хотя бы раз в неделю. Просто чтобы поддерживать MSYS2 в актуальном состоянии. В моем случае это выглядит вот так:
                                              Прикреплённая картинка
                                              Прикреплённая картинка
                                                Цитата Eretic @
                                                А тут сразу gcc, да еще под линукс, который я и в глаза не видел.

                                                Можно поставить эмулятор и в нём работать.
                                                я использую VirtualBox + Fedora - отлично работает.
                                                Для "Убинты" пришлось gcc отдельно устанавливать, а в Федору
                                                сразу всё было встроено.

                                                Добавлено
                                                Цитата Eretic @
                                                1) потоки в C++ создаются через std::thread?
                                                2) Потоком можно сделать класс? Точнее экземпляр класса? Есть какие то тонкости?
                                                3) какие стандартные средства есть для синхронизации доступа к данным между потоками? Просто я в винде всю жизнь использовал мьютексы и семафоры, а вот что есть в ++ даже не представляю.

                                                1) в Линуксе я использовал "pthread_create" и другие функции
                                                из <pthread.h>
                                                2) Да. Только так и работаю. Сделал базовый класс-поток, в котором
                                                виртуальная потоковая процедура - член класса. В библиотеку его,
                                                поскольку он полезен. Класс-поток конкретного проекта является наследником
                                                базового класса.
                                                3) Любые средства, какие есть в Линуксе. Те же семафоры.
                                                Тут лучше книги почитать. Лично я привык пользоваться критическими
                                                секциями, а в Линуксе я их не нашёл. Поэтому сделал класс "критическая секция"
                                                из семафора.

                                                Добавлено
                                                Цитата Eretic @
                                                4) основная проблема: как передать данные из одной программы в другую, чтобы работало и на винде и на линуксе?

                                                Если необходимо такое, тогда можно попытаться
                                                освоить кросс-платформенную библиотеку.
                                                Вообще многое можно использовать. Файлы, сокеты итд.
                                                Книги надо читать.
                                                Сообщение отредактировано: ЫукпШ -
                                                  Цитата Eretic @
                                                  как передать данные из одной программы в другую,
                                                  Я бы начал с проблемы "как из всех запущенных копий другой программы выбрать нужную, в которую хотим прередать".
                                                    Спасибо ребята.
                                                    Но пока, будете смеяться, никак не запущу поток. Выскакивает ошибка:
                                                    ExpandedWrap disabled
                                                      D:\Dev\Projects\CPP\Work\main.cpp:20:10: error: 'thread' is not a member of 'std'
                                                         20 |     std::thread th(input_thread);

                                                    #include <thread>
                                                    подключилось без проблем. И какого дьявола gcc нужно?
                                                      А как вы собираете: через gcc или g++?
                                                        Разница только в том, что gcc выдаёт на одну ошибку больше:
                                                        ExpandedWrap disabled
                                                          D:\Dev\Projects\CPP\Work\main.cpp:20:10: error: 'thread' is not a member of 'std'
                                                             20 |     std::thread th(input_thread);
                                                                |          ^~~~~~
                                                          D:\Dev\Projects\CPP\Work\main.cpp:4:1: note: 'std::thread' is defined in header '<thread>'; did you forget to '#include <thread>'?
                                                              3 | #include <vector>
                                                            +++ |+#include <thread>
                                                              4 | #include <string>

                                                        #include <thread> разумеется присутствует.
                                                        Похоже сборка криво встала, уже в который раз.
                                                        Буду делать на каком-нибудь C++ под винду. И надеюсь скомпилируется у них на gcc. А нет, так и чёрт с ними, итак целый день убил на бесконечную переустановку gcc :)
                                                          Eretic, сделал тебе пример. Попробуй у себя ...

                                                          Создай подкаталог для проекта, например: ~/dev/projects/test-threads
                                                          Создай в нем три файла:

                                                          test-threads.cpp

                                                          ExpandedWrap disabled
                                                            #include <iostream>
                                                            #include <thread>
                                                            #include <chrono>
                                                             
                                                            void printWithDelay(int id, double delay) {
                                                              for (int i = 0; i < 5; ++i) {
                                                                std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int>(delay * 1000)));
                                                                std::cout << "Thread [" << id << "] wrote: " << i << std::endl;
                                                              }
                                                            }
                                                             
                                                            int main() {
                                                              std::thread t1(printWithDelay, 1, 0.5);
                                                              std::thread t2(printWithDelay, 2, 0.6);
                                                              std::thread t3(printWithDelay, 3, 0.7);
                                                             
                                                              t1.join();
                                                              t2.join();
                                                              t3.join();
                                                             
                                                              return 0;
                                                            }

                                                          CMakeLists.txt

                                                          ExpandedWrap disabled
                                                            cmake_minimum_required(VERSION 3.0)
                                                            project(TestThreads)
                                                             
                                                            set(CMAKE_CXX_STANDARD 11)
                                                            set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
                                                             
                                                            add_executable(test-threads test-threads.cpp)

                                                          build.sh

                                                          ExpandedWrap disabled
                                                            #!/usr/bin/sh
                                                             
                                                            export PATH=/clang64/bin:$PATH
                                                             
                                                            mkdir build
                                                            cd build
                                                            cmake -G Ninja ..
                                                            ninja

                                                          Запусти сборку:

                                                          ExpandedWrap disabled
                                                            sh build.sh

                                                          Если все пройдет нормально, то в каталоге проекта появится подкаталог build, а в нем исполняемый файл. Если ninja не найден - установи его.

                                                          Посмотреть варианты и что установлено:

                                                          ExpandedWrap disabled
                                                            pacman -Ss ninja

                                                          Установить, например, clang64/mingw-w64-clang-x86_64-ninja:

                                                          ExpandedWrap disabled
                                                            pacman -S clang64/mingw-w64-clang-x86_64-ninja

                                                          И да, все манипуляции производятся в терминальном окне MSYS2. И не забывай - в Linux и вообще в *nix названия файлов и каталогов - регистрозависимые.
                                                            Цитата Eretic @
                                                            Похоже сборка криво встала, уже в который раз.
                                                            Буду делать на каком-нибудь C++ под винду.

                                                            Попробуй тут почитать - вдруг поможет.
                                                            Или здесь
                                                              ExpandedWrap disabled
                                                                build.sh: line 7: cmake: command not found

                                                              Сейчас переустановлю переустановлю...

                                                              Добавлено
                                                              ExpandedWrap disabled
                                                                $ sh build.sh
                                                                mkdir: cannot create directory ‘build’: File exists
                                                                CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
                                                                  Compatibility with CMake < 3.5 will be removed from a future version of
                                                                  CMake.
                                                                 
                                                                  Update the VERSION argument <min> value or use a ...<max> suffix to tell
                                                                  CMake that the project does not need compatibility with older versions.
                                                                 
                                                                 
                                                                -- The C compiler identification is unknown
                                                                -- The CXX compiler identification is unknown
                                                                CMake Error at CMakeLists.txt:2 (project):
                                                                  No CMAKE_C_COMPILER could be found.
                                                                 
                                                                  Tell CMake where to find the compiler by setting either the environment
                                                                  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
                                                                  the compiler, or to the compiler name if it is in the PATH.
                                                                 
                                                                 
                                                                CMake Error at CMakeLists.txt:2 (project):
                                                                  No CMAKE_CXX_COMPILER could be found.
                                                                 
                                                                  Tell CMake where to find the compiler by setting either the environment
                                                                  variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
                                                                  to the compiler, or to the compiler name if it is in the PATH.
                                                                 
                                                                 
                                                                -- Configuring incomplete, errors occurred!
                                                                ninja: error: loading 'build.ninja': ═х єфрхЄё  эрщЄш єърчрээ√щ Їрщы.


                                                              ExpandedWrap disabled
                                                                Andrey@DESKTOP-8J6CIOK MSYS /D/Dev/Projects/CPP/Work
                                                                $ pacman -Ss ninja
                                                                clangarm64/mingw-w64-clang-aarch64-cninja 3.7.9-1
                                                                    cninja, an opinionated cmake config manager
                                                                clangarm64/mingw-w64-clang-aarch64-gn 0.2131.85944ebc-1
                                                                    Meta-build system that generates build files for Ninja (mingw-w64)
                                                                clangarm64/mingw-w64-clang-aarch64-ninja 1.11.1-3
                                                                    Ninja is a small build system with a focus on speed (mingw-w64)
                                                                mingw32/mingw-w64-i686-cninja 3.7.9-1
                                                                    cninja, an opinionated cmake config manager
                                                                mingw32/mingw-w64-i686-ninja 1.11.1-3
                                                                    Ninja is a small build system with a focus on speed (mingw-w64)
                                                                mingw64/mingw-w64-x86_64-cninja 3.7.9-1
                                                                    cninja, an opinionated cmake config manager
                                                                mingw64/mingw-w64-x86_64-gn 0.2131.85944ebc-1
                                                                    Meta-build system that generates build files for Ninja (mingw-w64)
                                                                mingw64/mingw-w64-x86_64-ninja 1.11.1-3
                                                                    Ninja is a small build system with a focus on speed (mingw-w64)
                                                                ucrt64/mingw-w64-ucrt-x86_64-cninja 3.7.9-1
                                                                    cninja, an opinionated cmake config manager
                                                                ucrt64/mingw-w64-ucrt-x86_64-gn 0.2131.85944ebc-1
                                                                    Meta-build system that generates build files for Ninja (mingw-w64)
                                                                ucrt64/mingw-w64-ucrt-x86_64-ninja 1.11.1-3
                                                                    Ninja is a small build system with a focus on speed (mingw-w64)
                                                                clang32/mingw-w64-clang-i686-cninja 3.7.9-1
                                                                    cninja, an opinionated cmake config manager
                                                                clang32/mingw-w64-clang-i686-ninja 1.11.1-3
                                                                    Ninja is a small build system with a focus on speed (mingw-w64)
                                                                clang64/mingw-w64-clang-x86_64-cninja 3.7.9-1
                                                                    cninja, an opinionated cmake config manager
                                                                clang64/mingw-w64-clang-x86_64-gn 0.2131.85944ebc-1
                                                                    Meta-build system that generates build files for Ninja (mingw-w64)
                                                                clang64/mingw-w64-clang-x86_64-ninja 1.11.1-3 [installed]
                                                                    Ninja is a small build system with a focus on speed (mingw-w64)
                                                                msys/ninja 1.11.1-1
                                                                    Ninja is a small build system with a focus on speed
                                                                msys/ninja-emacs 1.11.1-1
                                                                    Ninja is a small build system with a focus on speed (Emacs mode)
                                                                msys/ninja-vim 1.11.1-1
                                                                    Ninja is a small build system with a focus on speed (vim mode)

                                                              Это уже MSYS2 с оф. сайта установлена.
                                                                Цитата Eretic @
                                                                Это уже MSYS2 с оф. сайта установлена.

                                                                Все же попробуйте установить linux на VirtualBox. Хотя странно у вас MinGW себя ведет. Я вам еще в #3 давал ссылку на скачивание MinGW (повторю, если не нашли для своей ОС). Это уже сразу Online установщик для MinGW-64

                                                                У меня, скачанный по этой ссылке MinGW-64, нормально собирает пример от Majestio через g++ (не через его build.sh). Правда я немного изменил его, используя int вместо double в задержке и выставил задержку в основном потоке. Так же добавил сообщения о завершении потока.

                                                                ExpandedWrap disabled
                                                                  #include <iostream>
                                                                  #include <thread>
                                                                  #include <chrono>
                                                                   
                                                                  void printWithDelay(int tid, int delay) {
                                                                    for (int i = 0; i < 5; ++i) {
                                                                      std::this_thread::sleep_for(std::chrono::milliseconds(delay));
                                                                      std::cout << "Thread ID = " << tid << " echo " << i << " . . ." << std::endl;
                                                                    }
                                                                    std::cout << "Thread [" << tid << "] exit." << std::endl;
                                                                  }
                                                                   
                                                                  int main() {
                                                                    std::thread t1(printWithDelay, 1, 500);
                                                                    std::thread t2(printWithDelay, 2, 750);
                                                                    std::thread t3(printWithDelay, 3, 900);
                                                                   
                                                                    t1.join();
                                                                    t2.join();
                                                                    t3.join();
                                                                   
                                                                    std::this_thread::sleep_for(std::chrono::milliseconds(20000));
                                                                    
                                                                    return 0;
                                                                  }


                                                                Вот так у меня выглядит вывод в консоль от этой программы
                                                                Прикреплённая картинка
                                                                Прикреплённая картинка


                                                                ADD: Скрин из wine под linux, но запускал установленный MinGW g++.exe. Он кстати более низкой версии, чем в установленный на linux

                                                                Прикреплённая картинка
                                                                Прикреплённая картинка
                                                                Сообщение отредактировано: macomics -
                                                                  Цитата ЫукпШ @
                                                                  Попробуй тут почитать - вдруг поможет.
                                                                  Или здесь

                                                                  Запутаешь человека ссылками на это старьё! >:(

                                                                  Установка MSYS2 уже включает разновсяческие тулчейны из mingw-w64 (не нужно отдельно ставить MINGW). Если они не установлены, они ставятся с помощью pacman. Тамошние потуги сборки внешних библиотек и инструментов также в большей части бесполезны, т.к. либы также ставятся с помощью pacman. На примере pkg-conf ...

                                                                  Смотрим что у нас установлено:

                                                                  ExpandedWrap disabled
                                                                    pacman -Ss pkg-conf

                                                                  Решили установить нужное:

                                                                  ExpandedWrap disabled
                                                                    pacman -S clang64/mingw-w64-clang-x86_64-pkg-config

                                                                  Очень много либ уже пердкомпилировано и собрано, остается только вот так установить. А самостоятельно собирать нужно ну что-то уж совсем экзотическое.
                                                                    А вот эта версия заработала!
                                                                    И даже VSCode подхватил, автоматом создав task.json, правда в него он прописал пути до старого, давно удаленного пакета. Переправил на нынешний пакет и всё ок.
                                                                    Спасибо огромное! Наконец-то займусь делом, тем более тут еще идеек подкинули :)

                                                                    До этого две версии инсталляторов:
                                                                    mingw-w64-v11.0.0.zip
                                                                    mingw-get-setup.exe
                                                                    и всякие msys, типа:
                                                                    msys2-x86_64-20240113.exe
                                                                      Цитата Eretic @
                                                                      Это уже MSYS2 с оф. сайта установлена.

                                                                      Для сборки моего примера должны быть установлены:

                                                                      1) Тулчейн для clang64
                                                                      2) cmake для clang64
                                                                      3) ninja для clang64

                                                                      Ошибка типа "С compiler тру-ляля unknown" говорит лишь о том, что хоть и путь /clang64/bin включен в build.sh, но по факту этот тулчейн не установлен, ЕМНИП. Надо аккуратно все установить, ну или в build.sh в путях прописать путь к другому, установленному тулчейну, например, /mingw64/bin.
                                                                        Цитата Eretic @
                                                                        Это уже MSYS2 с оф. сайта установлена.

                                                                        Напомню, команда pacman -Ss название показывает все, что найдено в репозитарии. А вот установленные пакеты обозначаются отдельно. См. скрин по стрелкам.
                                                                        Прикреплённая картинка
                                                                        Прикреплённая картинка
                                                                          Цитата Majestio @
                                                                          1) Тулчейн для clang64
                                                                          2) cmake для clang64
                                                                          3) ninja для clang64

                                                                          Да, папки были пустые. Меня это удивило, но раз инсталлятор так сделал, значит так надо. Я же не знаю какие папки и для чего нужны.
                                                                          Беда всех инет FAQ по minGW и MSYS в том, что ни в одном не нашел хотя бы краткого описания: что за пакеты ставят, для чего? Везде просто инструкции, типа ставим xxxx-yyyy-zzzz.??? и будет счастье :)
                                                                          Даже в данном случае. Что за clang? что за ulang и чем всё это отличается от minGW? Это хорошо когда человек знает что ему нужно, а когда нет времени читать книги на сотни страниц?
                                                                          ===============================================
                                                                          Ну да ладно. Главное работает :)

                                                                          Потоки сделал. Классы для приёма и первичной обработки внешних данных (первый поток) и для дальнейшей обработки вторым потоком сделал. Работают. Правда там упоминается один буфер на два потока, я сделал класс буфера (там же мьютекс для доступа нужен) с std::list, хуже не будет, зато избавляет от некоторых проблем.
                                                                          Теперь осталось еще одно условие:
                                                                          ExpandedWrap disabled
                                                                            поток №2 не должен постоянно опрашивать общий буфер.

                                                                          И здесь тупик. Если в винде есть такое замечательное средство, как WaitForXXXXObject и мьютексы для пробуждения трэда, то в std::thread я ничего похожего не нашел. Или цитату стоит воспринимать как опрос раз в секунду-две, с последующим засыпанием? Есть у кого дельные мысли?

                                                                          И еще. Уточнил на счет взаимодействия программ. Действительно на сокетах. Хорошая "крссплатформенная" засада :D
                                                                            Цитата Eretic @
                                                                            Даже в данном случае. Что за clang?

                                                                            Это одна из реализаций компилятора языка С/C++. Так же есть реализации от Microsoft (MSVC), Intel (Intel OneAPI), GNU Compiller Collection (gcc или g++).

                                                                            Цитата Eretic @
                                                                            что за ulang и чем всё это отличается от minGW?

                                                                            Не знаю где вы нашли ulang. Я первый раз о таком услышал от вас, но вот MinGW это пакет утилит для Windows, который собирает все (или большинство) программ из коллекции GCC. Сама GCC разрабатывается как Open Source проект под Unix операционные системы и включает кучу различных утилит, реализующих интерпретацию программ на многих языках программирования (не только C/C++, но и другие).

                                                                            MSYS и MSYS2 это дополнительные пакеты, который добавляет к MinGW возможности частичной установки по мере необходимости. Это позволяет не загружать, достаточно объемную, коллекцию программ из MinGW. Т.е. по сути это менеджеры пакетов, включенных в состав MinGW. Если этот менеджер что-то оставил пустым, то вы просто не установили этот пакет. Если он вам нужен, то его надо просто добавить.

                                                                            Цитата Eretic @
                                                                            И здесь тупик. Если в винде есть такое замечательное средство, как WaitForXXXXObject и мьютексы для пробуждения трэда, то в std::thread я ничего похожего не нашел. Или цитату стоит воспринимать как опрос раз в секунду-две, с последующим засыпанием? Есть у кого дельные мысли?

                                                                            Можно сделать lock на буфер.
                                                                              Цитата Eretic @
                                                                              Если в винде есть такое замечательное средство, как WaitForXXXXObject и мьютексы для пробуждения трэда, то в std::thread я ничего похожего не нашел.
                                                                              Дык и используй мьютексы. Поток исполнения сам по себе объектов синхронизации не содержит, даже в WinAPI. Что-то типа (внимание, синтетика!):
                                                                              ExpandedWrap disabled
                                                                                std::queue<std::string> msgs;
                                                                                std::mutex         queueLock;
                                                                                std::timed_mutex     evQueue;
                                                                                 
                                                                                void queueAdd(const std::string& str)
                                                                                {
                                                                                  std::lock_guard<std::mutex> guard(queueLock);
                                                                                 
                                                                                  msgs.emplace(str);
                                                                                  evQueue.unlock();
                                                                                }
                                                                                 
                                                                                std::string queueGet()
                                                                                {
                                                                                  std::lock_guard<std::mutex> guard(queueLock);
                                                                                  std::string                   str(std::move(msgs.front()));
                                                                                 
                                                                                  msgs.pop();
                                                                                  if (msgs.empty()) evQueue.lock();
                                                                                 
                                                                                  return str;
                                                                                }
                                                                                 
                                                                                std::mutex evExit;
                                                                                 
                                                                                void workThread()
                                                                                {
                                                                                  using namespace std::literals::chrono_literals;
                                                                                 
                                                                                  while (!evExit.try_lock())
                                                                                  {
                                                                                    if (evQueue.try_lock_for(100ms))
                                                                                    {
                                                                                      evQueue.unlock();
                                                                                      doSome(queueGet());
                                                                                    }
                                                                                  }
                                                                                }
                                                                                 
                                                                                int main()
                                                                                {
                                                                                  evExit.lock();
                                                                                  evQueue.lock();
                                                                                 
                                                                                  std::thread th1(workThread);
                                                                                 
                                                                                /* ... */
                                                                                  evExit.unlock();
                                                                                  th1.join();
                                                                                }
                                                                                Цитата macomics @
                                                                                MSYS и MSYS2 это дополнительные пакеты, который добавляет к MinGW возможности частичной установки по мере необходимости.

                                                                                Немножко наоборот :lol: MSYS2 - это система эмуляции Linux-окружения (если точнее - ArchLinux-окружения). В ней различные реализации MinGW-w64 подключаются как тулчейны. Для каждого вида тулчейна имеется набор предсобранных библиотек. И конечно, чтобы этим пользоваться - нужно нужное ставить с помощью пакетного менелдера pacman.

                                                                                Цитата Eretic @
                                                                                Я же не знаю какие папки и для чего нужны.

                                                                                На первых шагах тебе будет достаточно понять какие тулчейны есть в MSYS2. Давай сделаем поиск:

                                                                                ExpandedWrap disabled
                                                                                  pacman -Ss gcc

                                                                                Среди всего вывода выбираем именно gcc:

                                                                                ExpandedWrap disabled
                                                                                  clangarm64/mingw-w64-clang-aarch64-gcc-compat
                                                                                  mingw32/mingw-w64-i686-gcc
                                                                                  mingw64/mingw-w64-x86_64-gcc
                                                                                  ucrt64/mingw-w64-ucrt-x86_64-gcc
                                                                                  clang32/mingw-w64-clang-i686-gcc-compat
                                                                                  clang64/mingw-w64-clang-x86_64-gcc-compat

                                                                                Т.е. имеем список тулчейнов:
                                                                                • clangarm64
                                                                                • mingw32
                                                                                • mingw64
                                                                                • ucrt64
                                                                                • clang32
                                                                                • clang64
                                                                                Естественно, для того чтобы ими пользоваться - их нужно предварительно установить той же программой pacman. Сама же среда MSYS2 изначально устанавливает только базовые наборы утилит, при установке MSYS2 тулчейны автоматически не ставятся. Надеюсь, ситуация прояснилась.
                                                                                  Цитата Eretic @
                                                                                  Уточнил на счет взаимодействия программ. Действительно на сокетах. Хорошая "крссплатформенная" засада
                                                                                  Совершенно несложно учесть разницу в конструкторах объектов-сокетах. Делов-то на один API-вызов. Но не сокетами ж едиными. Есть ещё файлы в $TEMP (...я бы так и вообще намутил basic_socketstream<> и натравил на std::​(i|o|io)stream), eсть готовые библиотеки, если религия заказчик не возражает.
                                                                                    Цитата Majestio @
                                                                                    Немножко наоборот
                                                                                    Это даже не противоречит
                                                                                    Цитата Majestio @
                                                                                    MSYS2 - это система эмуляции Linux-окружения (если точнее - ArchLinux-окружения). В ней различные реализации MinGW-w64 подключаются как тулчейны. Для каждого вида тулчейна имеется набор предсобранных библиотек. И конечно, чтобы этим пользоваться - нужно нужное ставить с помощью пакетного менелдера pacman.

                                                                                    сказанному тут
                                                                                    Цитата macomics @
                                                                                    MSYS и MSYS2 это дополнительные пакеты, который добавляет к MinGW возможности частичной установки по мере необходимости. Это позволяет не загружать, достаточно объемную, коллекцию программ из MinGW. Т.е. по сути это менеджеры пакетов, включенных в состав MinGW. Если этот менеджер что-то оставил пустым, то вы просто не установили этот пакет. Если он вам нужен, то его надо просто добавить.

                                                                                    Есть там эмуляция среды linux или нет - не важно. Главное эффект. Пакетный менеджер для MinGW
                                                                                      Цитата macomics @
                                                                                      Это даже не противоречит

                                                                                      Цитата macomics @
                                                                                      Пакетный менеджер для MinGW

                                                                                      Противоречие самое малое - пакетный менеджер, он для MSYS2, а не для MinGW. MinGW - там часть. Противоречие в том, что не MinGW там "главный" :lol:
                                                                                      Иными словами что кого включает. MSYS2 и его утиль включает MinGW. Но не наоборот. Это как сказать, что "Linux - это дополнительные пакеты, который добавляет к gcc возможности частичной установки по мере необходимости" ;)
                                                                                        Цитата Qraizer @
                                                                                        Дык и используй мьютексы.

                                                                                        Пытаюсь. Правда немного по другому.
                                                                                        ExpandedWrap disabled
                                                                                          class IOBuffer
                                                                                          {
                                                                                          private:
                                                                                              std::list<std::string> buf;
                                                                                              std::condition_variable io_cond;
                                                                                          ....
                                                                                           
                                                                                              virtual void put(std::string in_str) {
                                                                                                  std::lock_guard<std::mutex> lock(io_mutex);
                                                                                                  buf.push_back(in_str);
                                                                                                  io_cond.notify_one();
                                                                                              }
                                                                                           
                                                                                              virtual std::string _wait()
                                                                                              {
                                                                                                  std::unique_lock<std::mutex> guard(io_mutex);
                                                                                                  io_cond.wait(guard, []{return !buf.empty();});
                                                                                                  std::string tmp = get_unlock();
                                                                                                  guard.unlock();
                                                                                                  return tmp;
                                                                                              }
                                                                                           
                                                                                          ....
                                                                                           
                                                                                          void output_thread(IOBuffer *io_buffer)
                                                                                          {
                                                                                              OUTString str;
                                                                                              str.clear();
                                                                                              str.append_string(io_buffer->_wait());

                                                                                        То есть в начале потока, что должен извлекать данные с общего буфера и отправлять в другую программу, вызываем метод _wait(), который по идее организует остановку потока до тех пор, пока не придут данные в буфер (io_cond.notify_one()).
                                                                                        Проблемка в том, что
                                                                                        io_cond.wait(guard, []{return !buf.empty();});
                                                                                        ругается, мол нельзя использовать this. А главное вместо лямбды нельзя подставить функцию. Вот пытаюсь придумать, как обойти ограничение, очень уж идея понравилась на счет засыпания треда.

                                                                                        Добавлено
                                                                                        Цитата macomics @
                                                                                        Это одна из реализаций компилятора языка С/C++. Так же есть реализации от Microsoft (MSVC), Intel (Intel OneAPI), GNU Compiller Collection (gcc или g++).

                                                                                        Цитата Majestio @
                                                                                        Надеюсь, ситуация прояснилась.

                                                                                        Спасибо ребята, теперь более менее понятно. Скоро линукс по программе, там уже поглубже копну :)

                                                                                        Добавлено
                                                                                        Кстати, что за ошибку выдаёт VSCode:
                                                                                        ExpandedWrap disabled
                                                                                          на вложенную функцию "this" нельзя ссылаться внутри тела лямбды, если она не находится в списке записей

                                                                                        Это где я в лямбду пытаюсь подставить строку из класса.

                                                                                        Добавлено
                                                                                        Заработало!!!
                                                                                        Надо было this в [] добавить:
                                                                                        ExpandedWrap disabled
                                                                                          io_cond.wait(guard, [this]{return !buf.empty();});
                                                                                          Ну, я пытался оградить тебя от условных переменных, потому что их нет в WinAPI. Точнее, есть, в лице событий, и они в общем-то удобнее в использовании, но менее функциональны, т.к. способны – посредством WaitForMultipleObjects() – покрыть лишь некоторый поддиапазон возможных комбинаций условий. Но коли ты уже взялся за них, на здоровье.
                                                                                          Цитата Eretic @
                                                                                          Проблемка в том, что
                                                                                          io_cond.wait(guard, []{return !buf.empty();});
                                                                                          ругается, мол нельзя использовать this.
                                                                                          Можно. Просто передай его списком захвата:
                                                                                          ExpandedWrap disabled
                                                                                            io_cond.wait(guard, [this]{return !buf.empty();});
                                                                                          Цитата Eretic @
                                                                                          А главное вместо лямбды нельзя подставить функцию.
                                                                                          Можно. Подойдёт любой функциональный объект с синопсисом bool(). В частности и простые функции, но с ними неудобно то, что у них не должно быть параметров, а лямбды с захватом это решают влёгкую.

                                                                                          Добавлено
                                                                                          Цитата Eretic @
                                                                                          Заработало!!!
                                                                                          А. О. Ну нормалёк, чё. :good:

                                                                                          Добавлено
                                                                                          P.S. С this в списке захвата, как и с любым указателем или ссылкой, нужно быть аккуратным. Время жизни лямбды может превысить время жизни подссыльного объекта. В общем случае я бы рекомендовал захватывать через weak_ptr. Но не счас, слишком много сразу – голова поломается ещё.
                                                                                            Цитата Qraizer @
                                                                                            Ну, я пытался оградить тебя от условных переменных, потому что их нет в WinAPI. Точнее, есть, в лице событий, и они в общем-то удобнее в использовании, но менее функциональны, т.к. способны – посредством WaitForMultipleObjects() – покрыть лишь некоторый поддиапазон возможных комбинаций условий. Но коли ты уже взялся за них, на здоровье.

                                                                                            Рыская по инету я естественно встречал это понятие, но не понял о чём вообще речь. Потом случайно набрел на книгу некоего Уильямс Э. - "Параллельное программирование на C++". Прочитал главы, посвященные мьютексам и понял что мне нужно :) Поскольку читал бегло, еще не всё понял, а контейнеры потоков вообще пропустил. Но на досуге добью книжёнку.

                                                                                            Цитата Qraizer @
                                                                                            голова поломается ещё

                                                                                            Уже пухнет :) Сколько сегодня инета перелопатил - уму непостижимо. Но в целом картина многопоточности более-менее становится понятной. Во многом похожа на виндозную, разве что нет некоторых удобных вещей (или я их пока не нашел), а может просто кажется в силу моей привычки.
                                                                                            =============================================
                                                                                            Первый модуль готов, ввод/вывод работает как положено, строго по заданию (нет постоянного опроса буфера, нет глобальных переменных и тд).
                                                                                            Завтра займусь сокетами. Надеюсь удастся подобрать что-нибудь универсальное. А то время поджимает.
                                                                                              Цитата Qraizer @
                                                                                              Совершенно несложно учесть разницу в конструкторах объектов-сокетах. Делов-то на один API-вызов. Но не сокетами ж едиными. Есть ещё файлы в $TEMP (...я бы так и вообще намутил basic_socketstream<> и натравил на std::​(i|o|io)stream), eсть готовые библиотеки, если религия заказчик не возражает.

                                                                                              Можно вполне и так. Если не учесть, что ранее macomics пацанов туманил относительно MSYS2 :lol:

                                                                                              Цитата macomics @
                                                                                              Затем, что по заданию она должна компилироваться на linux. И вот тут косяк, если из-за как-то не учтенной особенности linux, не выученной своевременно, программа просто не сможет откомпилироваться.

                                                                                              Вот элементарный пример. Для взаимодействия предложили использовать socket. Но на Windows для работы с socket надо использовать WSAStartup и WSACleanup, которых нету в linux. Т.е. с виду работоспособный код для Windows под linux просто выдаст ошибку отсутствия функций.

                                                                                              Действительно, разная реализация сокетов в Windows и Linux имеет место. Но, что касаемо MSYS2, то лучше сперва прокачать вопрос, а потом утверждать. Дело в том, что перечисленные мною выше тулчейны не смогут собрать код для Linux-сокетов, просто не найдут Linux-специфических заголовков. Но все же MSYS2 - эмулятор Linux и у него кроме mingw-w64-* есть еще свой тулчейн /msys. Приведу пример, топикстартеру, уверен, пригодится ...

                                                                                              Сперва установим необходимое

                                                                                              ExpandedWrap disabled
                                                                                                pacman -S msys/gcc
                                                                                                pacman -S msys/gcc-libs
                                                                                                pacman -S msys/binutils
                                                                                                pacman -S msys/cmake
                                                                                                pacman -S msys/ninja

                                                                                              Да, при установке некоторые пакеты могут быть поставлены как зависимости к ранее поставленным пакетам, в этом случае можно повторно не ставить. К примеру установка /msys/gcc может подтянуть сразу /msys/gcc-libs и /msys/binutils. Я уже не помню, но что-то такое было. Не суть.

                                                                                              Тестируем "родной" тулчейн

                                                                                              По уже знакомому сценарию делаем проект, пусть в каталоге ~/dev/projects/echo-test, туда кладем файлы:

                                                                                              server.cpp

                                                                                              ExpandedWrap disabled
                                                                                                #include <iostream>
                                                                                                #include <cstring>
                                                                                                #include <sys/socket.h>
                                                                                                #include <netinet/in.h>
                                                                                                #include <unistd.h>
                                                                                                 
                                                                                                int main() {
                                                                                                    int server_fd, new_socket, valread;
                                                                                                    struct sockaddr_in address;
                                                                                                    int opt = 1;
                                                                                                    int addrlen = sizeof(address);
                                                                                                    char buffer[1024] = {0};
                                                                                                    const char *hello = "Hello from server";
                                                                                                 
                                                                                                     if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
                                                                                                        perror("socket failed");
                                                                                                        exit(EXIT_FAILURE);
                                                                                                    }
                                                                                                 
                                                                                                     if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
                                                                                                        perror("setsockopt");
                                                                                                        exit(EXIT_FAILURE);
                                                                                                    }
                                                                                                    address.sin_family = AF_INET;
                                                                                                    address.sin_addr.s_addr = INADDR_ANY;
                                                                                                    address.sin_port = htons(8080);
                                                                                                 
                                                                                                     if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
                                                                                                        perror("bind failed");
                                                                                                        exit(EXIT_FAILURE);
                                                                                                    }
                                                                                                    if (listen(server_fd, 3) < 0) {
                                                                                                        perror("listen");
                                                                                                        exit(EXIT_FAILURE);
                                                                                                    }
                                                                                                    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
                                                                                                        perror("accept");
                                                                                                        exit(EXIT_FAILURE);
                                                                                                    }
                                                                                                    valread = read(new_socket, buffer, 1024);
                                                                                                    printf("%s\n", buffer);
                                                                                                    send(new_socket, hello, strlen(hello), 0);
                                                                                                    printf("Hello message sent\n");
                                                                                                    return 0;
                                                                                                }

                                                                                              client.cpp

                                                                                              ExpandedWrap disabled
                                                                                                #include <iostream>
                                                                                                #include <cstring>
                                                                                                #include <sys/socket.h>
                                                                                                #include <arpa/inet.h>
                                                                                                #include <unistd.h>
                                                                                                 
                                                                                                int main() {
                                                                                                    int sock = 0, valread;
                                                                                                    struct sockaddr_in serv_addr;
                                                                                                    const char *hello = "Hello from client";
                                                                                                    char buffer[1024] = {0};
                                                                                                    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
                                                                                                        std::cerr << "\n Socket creation error \n";
                                                                                                        return -1;
                                                                                                    }
                                                                                                    serv_addr.sin_family = AF_INET;
                                                                                                    serv_addr.sin_port = htons(8080);
                                                                                                    if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
                                                                                                        std::cerr << "\nInvalid address/ Address not supported \n";
                                                                                                        return -1;
                                                                                                    }
                                                                                                    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
                                                                                                        std::cerr << "\nConnection Failed \n";
                                                                                                        return -1;
                                                                                                    }
                                                                                                    send(sock, hello, strlen(hello), 0);
                                                                                                    std::cout << "Hello message sent\n";
                                                                                                    valread = read(sock, buffer, 1024);
                                                                                                    std::cout << buffer << std::endl;
                                                                                                    return 0;
                                                                                                }

                                                                                              CMakeLists.txt

                                                                                              ExpandedWrap disabled
                                                                                                cmake_minimum_required(VERSION 3.0)
                                                                                                project(TestThreads)
                                                                                                 
                                                                                                set(CMAKE_CXX_STANDARD 11)
                                                                                                set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
                                                                                                 
                                                                                                add_executable(server server.cpp)
                                                                                                add_executable(client client.cpp)

                                                                                              build.sh

                                                                                              ExpandedWrap disabled
                                                                                                #!/usr/bin/sh
                                                                                                 
                                                                                                mkdir build
                                                                                                cd build
                                                                                                cmake -G Ninja ..
                                                                                                ninja

                                                                                              Запускаем сборку. Следует заметить, что в пакетном файле переменную окружения PATH мы не модифицируем. Тем самым запускается "родная" версия cmake, которая также ищет "родные" компиляторы и бинутилсы, которые располагаются непосредственно в /usr/bin. После сборки получаем два исполняемых файла формата PE (виндовых). Однако, хоть и проект был собран статически, одна динамическая зависимость осталась. Для работы исполняемым файлам нужно положить рядом msys-2.0.dll (его можно взять из /usr/bin).

                                                                                              Запускаем сперва server.exe - программа висит и ждёт. Запускаем во втором окне client.exe. Обе программы завершают свою работу. При этом в окне sever.exe видим вывод:

                                                                                              ExpandedWrap disabled
                                                                                                Hello from client
                                                                                                Hello message sent

                                                                                              А в окне client.exe:

                                                                                              ExpandedWrap disabled
                                                                                                Hello message sent
                                                                                                Hello from server

                                                                                              Вот, собственно, такими нехитрыми манипуляциями мы собрали Linux-специфичный проект, и запустили его под M$ Windows :thanks:
                                                                                                Цитата Majestio @
                                                                                                Но все же MSYS2 - эмулятор Linux и у него кроме mingw-w64-* есть еще свой тулчейн /msys.

                                                                                                Thanks за пример, даже не верится, что под винду заработает без WSAxxxx. В целом, то же самое, что я уже делал неоднократно, вот например из последнего: https://github.com/MrDemonid/Sync-time-from-NTP

                                                                                                Но тогда уж вопрос на засыпку. У меня все попытки установить MSYS2 провалились, скорее всего из-за ошибок установки. И сейчас у меня просто minGW, в которой нет даже намёка на MSYS, то есть тупо вообще нет соответствующей консоли, так что ничего доставить не могу. И как быть? Ставить заново MSYS2? Так то я не против попробовать снова, но что делать с текущим minGW?
                                                                                                Сейчас прошелся поиском и не нашел в папке minGW ключевых инклюдов:
                                                                                                inet.h и socket.h
                                                                                                так что по любому что-то делать нужно. А я то наивно думал, что самое сложное позади :(
                                                                                                  MSYS2 вроде заработал, всего одна ошибка при установке. Проект компилируется, правда только из терминала, VSCode поломался и ни в какую не создаёт нормальные json файлы. Подружить бы его с makefile для cmake, но пока итак пойдёт.
                                                                                                  Осталось только доделать.
                                                                                                  Всем спасибо за помощь и советы!
                                                                                                    Цитата Eretic @
                                                                                                    Так то я не против попробовать снова, но что делать с текущим minGW?

                                                                                                    Это вопрос тем, кто посоветовал :jokingly:
                                                                                                      Цитата Eretic @
                                                                                                      Сейчас прошелся поиском и не нашел в папке minGW ключевых инклюдов:
                                                                                                      inet.h и socket.h

                                                                                                      А нет ли там файлов "windows.h", "winsock.h", "winsock2.h", "wininet.h" ?
                                                                                                      Вариант поиска:
                                                                                                      Во всех файлах *.h ищем ключевое слово "socket".

                                                                                                      Добавлено
                                                                                                      Цитата Eretic @
                                                                                                      так что по любому что-то делать нужно. А я то наивно думал, что самое сложное позади :(

                                                                                                      Сложности только начинаются.
                                                                                                      Поскольку кроме поставленной задачи, ты начал решать
                                                                                                      ещё одну задачу - "кросплатформенность". Ещё не известно, что сложнее.
                                                                                                      Наверняка будет много сюрпризов. Обычный из них - всё было хорошо и правильно для Виндуса.
                                                                                                      При попытке собрать приложение плд Линуксом исходники просто не компилируются.
                                                                                                      Сообщение отредактировано: ЫукпШ -
                                                                                                        Цитата ЫукпШ @
                                                                                                        А нет ли там файлов "windows.h", "winsock.h", "winsock2.h", "wininet.h" ?

                                                                                                        Есть. Но это вариант виндозный и немного не то. Хотя на нём конечно получилось бы намного красивее и проще, чем сейчас замучиваю с select() :)
                                                                                                        Цитата ЫукпШ @
                                                                                                        Поскольку кроме поставленной задачи, ты начал решать
                                                                                                        ещё одну задачу - "кросплатформенность". Ещё не известно, что сложнее.

                                                                                                        Меня больше пугают установки неизвестных доселе пакетов, структуры которых я не понимаю. Теперь вот более-менее разобрался. О кроссплатформенности мне пока рано думать. Я же в качестве студента на каникулы заявку подал. Вряд ли кто-то ожидает, что бестолковый студент сразу начнет решать сложнейшие задачи, вызывающие головную боль даже у профессионалов :)
                                                                                                        А программки заработали. Единственный косяк - это забыл что в первый параметр select() нужно передавать значение на 1 больше сокета (максимального из набора) и почти час не мог понять - отчего постоянно выходит только по таймауту. Да, функция допотопная, но зато совместимость 100% и задаче отвечает полностью (приложения не должны зависеть друг от друга, а продолжать спокойно работу в случае закрытия одного их них) :)

                                                                                                        Добавлено
                                                                                                        Цитата ЫукпШ @
                                                                                                        При попытке собрать приложение плд Линуксом исходники просто не компилируются.

                                                                                                        Но ведь я компилирую gcc? То есть тем самым компилятором, что является основным в линуксе. Что тут может пойти не так?
                                                                                                          Цитата Eretic @
                                                                                                          Но ведь я компилирую gcc? То есть тем самым компилятором, что является основным в линуксе. Что тут может пойти не так?

                                                                                                          Все просто. Нужно просто прочесть расшифровку MinGW - Minimalist GNU for Windows. Там нет и не может быть заголовочных файлов для Linux, т.к. это инструмент заточен именно для Windows.
                                                                                                            Цитата Majestio @
                                                                                                            ужно просто прочесть расшифровку MinGW - Minimalist GNU for Windows.

                                                                                                            Так я сейчас перешел с minGW на MSYS2.
                                                                                                            К тому же из инклюдов у меня только:
                                                                                                            #include <iostream>
                                                                                                            #include <thread>
                                                                                                            #include <algorithm>
                                                                                                            #include <list>
                                                                                                            #include <condition_variable>
                                                                                                            #include <mutex>
                                                                                                            #include <chrono>
                                                                                                            #include <sys/socket.h>
                                                                                                            #include <sys/select.h>
                                                                                                            #include <arpa/inet.h>
                                                                                                            #include <unistd.h>

                                                                                                            Вроде ничего специфического, чисто плюсовые примочки, которые должны быть реализованы под любую платформу. Разве нет?
                                                                                                              Цитата Eretic @
                                                                                                              которые должны быть реализованы под любую платформу. Разве нет?

                                                                                                              Чтобы код был кроссплатформенным, нужно примерно следующее:

                                                                                                              ExpandedWrap disabled
                                                                                                                #ifdef _WIN32
                                                                                                                    // Заголовки для Windows с использованием MinGW-w64
                                                                                                                    #include <winsock2.h>
                                                                                                                    #include <ws2tcpip.h>
                                                                                                                    #pragma comment(lib, "ws2_32.lib")
                                                                                                                #else
                                                                                                                    // Заголовки для Linux
                                                                                                                    #include <sys/socket.h>
                                                                                                                    #include <arpa/inet.h>
                                                                                                                    #include <netinet/in.h>
                                                                                                                    #include <unistd.h>
                                                                                                                #endif

                                                                                                              Тулчейн /mingw32 будет использовать первую часть (виндовую), а /msys будет использовать вторую часть (линуховую). Соответственно, и в дальнейшей реализации нужно писать отдельные части для виндовс и линух, помещая их в блоки #ifdef. В стандарте С++ нет унифицированной работы с TCP/IP, поэтому указанные выше заголовки - платформозависимые.
                                                                                                                Цитата Majestio @
                                                                                                                #ifdef _WIN32
                                                                                                                    // Заголовки для Windows с использованием MinGW-w64
                                                                                                                   #include <winsock2.h>
                                                                                                                   #include <ws2tcpip.h>
                                                                                                                   #pragma comment(lib, "ws2_32.lib")

                                                                                                                А зачем мне winsock, если у меня и без него всё работает? Говорю же, у меня подключено как раз вот это:
                                                                                                                Цитата Majestio @
                                                                                                                #else
                                                                                                                    // Заголовки для Linux
                                                                                                                   #include <sys/socket.h>
                                                                                                                   #include <arpa/inet.h>
                                                                                                                   #include <netinet/in.h>
                                                                                                                   #include <unistd.h>
                                                                                                                #endif

                                                                                                                И прекрасно работает под виндой. Еще разберусь, почему клиент не опознаёт потерю связи и можно сдать задание. С другой стороны, не распознает и фиг с ней, всё равно данные будут потеряны (в задаче нет ни слова о их хранении до восстановления связи).

                                                                                                                Но в принципе можно проверить. Если есть желающий попробовать компильнуть под линуксом и проверить в работе, то пишите. Как только закончу - вышлю :) Заодно и узнаем, можно ли обойтись без #ifdef.
                                                                                                                  Цитата Eretic @
                                                                                                                  А зачем мне winsock, если у меня и без него всё работает? Говорю же, у меня подключено как раз вот это:

                                                                                                                  А потому, что дальше у тебя возникнет желание использовать WinAPI, а с "линуксовым" тулчейном тебя поприветствует облом. Нет в нем поддержки Windows, только ограниченная эмуляция (трансляция) линуховых вызовов в виндовые.
                                                                                                                    Ну как, найдётся желающий протестировать под линуксом?
                                                                                                                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                                                                    0 пользователей:


                                                                                                                    Рейтинг@Mail.ru
                                                                                                                    [ Script execution time: 0,1621 ]   [ 24 queries used ]   [ Generated: 27.04.24, 06:02 GMT ]