Программирование на C (Си) в Linux (часть 2)

Поділитися
Вставка
  • Опубліковано 2 жов 2024
  • Сегменты памяти процесса и их права доступа, порождение процессов системным вызовом fork() и принцип COW (copy-on-write), порождение нитей pthread
    Об этом и о многом другом см. books.google.r...

КОМЕНТАРІ • 44

  • @lex.mikachev
    @lex.mikachev 3 роки тому +2

    Долго и упорно бился с ошибкой из-за вызова неизвестных функций: pthread_create() и pthread_join(). Проблема решилась просто - в Makefile указал ещё и LDFLAGS=-lpthread, получилось следующее (спасибо за наводку авторам на StackOverfow):
    CFLAGS=-Wall -pthread
    LDFLAGS=-lpthread
    После этого всё отлично скомпилировалось и собралось :-)
    Спасибо, Дмитрий, за интересный урок. Это стало отправной точкой для дальнейшего изучения программирования под Linux.
    P.S.: gcc version 9.3.0 при компиляции выносит глобальные константы из секции с исполняемым кодом (r-xp) в отдельную секцию (r--p). Радует, что разработчики делают работу над ошибками :-)

  • @vrabosh
    @vrabosh 3 роки тому +1

    Абалденно.

  • @alexanderscheffer3882
    @alexanderscheffer3882 4 роки тому +2

    Большое спасибо Дмитрий! Очень помогло. Теперь все стало по местам в голове :)

  • @zurabashot
    @zurabashot 6 років тому

    Отличная подача, главное это сочетание теории и практики. Вопрос который не дает покоя, что это за заголовочные файлы, что из себя представляют и зачем нужны? С библиотеками или shared object понятно, там за тебя написаны программы, которые использует твоя программа. Что за заголовочные файлы и почему они не библиотека, если их функция одинакова как я понимаю? А еще бывают devel пакеты, тоже непонятно для чего, заголовочные файлы библиотеки?

    • @DmitryKetov
      @DmitryKetov  6 років тому

      Заголовочные файлы содержат описания типов данных, которыми манипулирует библиотека и декларации ее функций, котороые можно вызывать. Все это нужно копилятору для того, что бы проверить *правильность* использования этой библиотеки программистом в ее программе.
      Любую библиотеку можно легко использовать *без* заголовочных файлов, но за правильность тогда никто не поручится и вся отвественность тогда будет на программисте. А *с* заголовочными файлами компилятор может произвести некоторые проверки.

    • @DmitryKetov
      @DmitryKetov  6 років тому

      В devel пакетах действительно содержатся заголовочные файлы библиотеки и "компоновочное имя" самой библиотеки, а зачастую еще и варинат тойже библиотеки для статической линковки - см. asciinema.org/a/198815

    • @zurabashot
      @zurabashot 6 років тому

      Спасибо!

  • @sergeystal15
    @sergeystal15 5 років тому

    между первой частью и второй есть какая то пропасть =))))
    и у меня в (gcc v 8.3.0 Debian (8,3,0-6) ) глобальная переменная во всех случаях r--p,
    а еще есть ? =) интересно черт возьми =) я просто обязан теперь книгу купить =)
    я стал ближе к написанию змейки в терминале )))
    большое спасибо было очень увлекательно.

    • @DmitryKetov
      @DmitryKetov  4 роки тому

      Не, глобальная не может быть r--p. Только rw-p :)

  • @АнгелИнокентий

    Очень интересно. Только Я вот не понял, откуда брать код, как эту программу логически самому построить? Что посмотреть?

    • @DmitryKetov
      @DmitryKetov  9 місяців тому +1

      Есть такая наука о том как писать программы - программирование.

  • @vinar9232
    @vinar9232 2 місяці тому

    Что думаете о языке Golang как замену C ?

    • @DmitryKetov
      @DmitryKetov  2 місяці тому

      @@vinar9232 думаю что замена C/C++ этo rust, раз у D ничего не вышло

  • @CraBiKun
    @CraBiKun 4 роки тому

    А программы написанные для виндовс будут также в /проц мапиться, запущенные под вайном? Или там другой порядок секций?

    • @DmitryKetov
      @DmitryKetov  4 роки тому

      В /proc процессы, а не программы. Так как wine выполняет каждую win программу в своём linux процессе, то будут

  • @ВладимирКазанцев-ц9т

    Подскажите, не совсем понял как в переменную pid попадают 2 значения. У меня в голове такая модель - переменная поименованная область памяти и получается соответствие имени значению. За счёт каких промежуточных звеньев имя видит два значения? Какова схема этого явления?

    • @DmitryKetov
      @DmitryKetov  3 роки тому

      В каждом процессе это своя именованная область памяти, всего процессов два - родитель и ребенок. Собственно две области - два значения, по одному на процесс.

    • @ВладимирКазанцев-ц9т
      @ВладимирКазанцев-ц9т 3 роки тому

      @@DmitryKetov С зтим понятно, но как эти два значения хранятся в одной переменной pid. В чем секрет? 2 области , 2 значения, 2 процесса , а переменная 1 - pid. Или как то эта переменная специфическим образом обращается к этим двум областям? Уж простите Дмитрий, что глупые вопросы задаю.

    • @DmitryKetov
      @DmitryKetov  3 роки тому

      Переменная это есть "именованная область памяти". Имя - одно, области для хранения - две.

  • @dobr-sib
    @dobr-sib 6 років тому

    Супер. Все понятно. Хотелось бы спросить Будет ли еще разбор программирования на Си в Линуксе?

    • @DmitryKetov
      @DmitryKetov  6 років тому

      Да, будет. Пишите, о чем было бы интересно узнать.

    • @winterfox8319
      @winterfox8319 6 років тому

      Вы реально крут ! Подписываюсь на ваш канал и жду ваших видео с нетерпением ...
      Очень интересно Си в Linux и тема разработки модулей ядра !

    • @zurabashot
      @zurabashot 6 років тому

      Очень много интересных тем уже подробно и главное доступно раскрыто. Хотелось бы увидеть еще что-нибудь про виртуализацию.

    • @DmitryKetov
      @DmitryKetov  6 років тому +1

      "Что-нибудь" это как-то бессмысленно :)
      Литературы море. Зачем еще один велосипед?

    • @severginamarina
      @severginamarina 2 роки тому

      @@DmitryKetov вывод графики, пока без графических библиотек, например для написания собственного рендера методом обратной трассировки

  • @АлександрНовиков-я3ц

    глобальная константная переменная вроде и должна попадать в секцию кода. Секция кода вроде для нескольких экземпляров программы остается одна, когда для всех остальных секций выделяется память на каждый экземпляр. А так как константная глобальная переменная неизменно присутствует в каждом экземпляре, то чтобы не выделять лишнюю память она находится в секции кода. Насколько я правильно помню. П.с. я только начал изучать программирование, могу ошибаться.

    • @DmitryKetov
      @DmitryKetov  4 роки тому +1

      Нет, не должна. В .text только исполняемый код ибо право на исполнение. Что касается страниц памяти любых файлов (не только elf) то все они будут лежать в памяти страничного кэша один раз покуда их страницы не подвергнутся изменению, сколько бы процессов с файлом не работало.

    • @АлександрНовиков-я3ц
      @АлександрНовиков-я3ц 4 роки тому

      @@DmitryKetov Секция кода создаётся для хранения исполняемого машинного кода, из которого, собственно говоря, и состоит исполняемая программа. Естественно, область памяти, выделенная под секцию кода, доступна задаче на исполнение. С другой стороны, операционная система не позволяет пользовательским задачам модифицировать содержимое секции кода; попытка задачи сделать такую модификацию рассматривается как нарушение защиты памяти. Сделано это по достаточно простой причине: если в системе одновременно запущенно в виде задач несколько экземпляров одной и той же программы, операционная система обычно хранит в физической памяти только один экземпляр машинного кода такой программы. Это верно даже в случае, если запущенные задачи принадлежат разным пользователям и имеют разные полномочия в системе. Если одна из таких задач модифицирует "свою" секцию кода, очевидно, что это помешает работать остальным - ведь они используют (физически) ту же самую секцию кода. Однако на чтение секция кода доступна, так что её можно использовать не только для кода как такового, но и для хранения константных данных - такой информации, которая не изменяется во время выполнения программы.
      А.В. Столяров.
      Программирование. Введение в профессию. Том 2: Низкоуровневое программирование.
      стр.41

    • @АлександрНовиков-я3ц
      @АлександрНовиков-я3ц 4 роки тому

      @@DmitryKetov также и строковые литералы.
      А.В. Столяров.
      Программирование. Введение в профессию. Том 2: Низкоуровневое программирование.
      стр.265

    • @DmitryKetov
      @DmitryKetov  4 роки тому +1

      @@АлександрНовиков-я3ц Опыт - вершина познания (с) Проведите собственными руками и узрите :)

    • @АлександрНовиков-я3ц
      @АлександрНовиков-я3ц 4 роки тому

      @@DmitryKetov Проверял, у меня не попадало в секцию кода. Однако в книге и написано может, а не должно, что мы и увидели на вашем примере. Ещё интересный пример можно было провести создав указатель на неконстантную область памяти, присвоив ему адрес глобальной константной переменной, приведя к (void *). И посмотреть что указатель действительно указывает на тот же адрес памяти что и у глобальной переменной. При попытке изменить значение глобальной переменной через указатель программа компилируется, но при запуске программы выдаёт ошибку сегментирования.
      А видео очень крутое( и первая и вторая часть). Спасибо.

  • @1nzhener
    @1nzhener 5 років тому

    А как распределить процессорное время между потоками? Например, первый выполняется раз в миллисекунду, второй раз в 50 миллисекунд ?

    • @fwd8789
      @fwd8789 4 роки тому

      Смотря как потоки реализованы в ядре или в userspace. В Линукс они в ядре существуют и воспринимаются им как некоторое универсальное понятие "задача". Ну и есть разные алгоритмы планирования

    • @DmitryKetov
      @DmitryKetov  4 роки тому

      Краткий ответ - а никак, потому что незачем.

    • @fwd8789
      @fwd8789 4 роки тому

      @@DmitryKetov Как незачем? А если это веб-сервер и имеется поток диспетчера и два рабочих потока, которые находятся в состоянии готовности. Какой поток выбрать следующим?

    • @DmitryKetov
      @DmitryKetov  4 роки тому

      @@fwd8789 В исходном вопросе про ДОЛЮ времени, а у вас про ПОРЯДОК, а это две большие разницы, см. ua-cam.com/video/v7gsUPKcCQc/v-deo.html ua-cam.com/video/Vbl0Rk_oZW4/v-deo.html я эту разницу студентам не раз втолковывал, у них даже курсовик был 😂

    • @fwd8789
      @fwd8789 4 роки тому

      @@DmitryKetov Спасибо. Сейчас перечитал у Таненбаума, что потоку выделяется квант времени, по истечении которого его работа приостанавливается, либо пока он не заблокируется вводом-выводом.

  • @fwd8789
    @fwd8789 5 років тому

    а как форк() умудряется возвратить 0 в дочерний процесс? он что - волшебник и все знает?

    • @DmitryKetov
      @DmitryKetov  5 років тому

      Типа того :)

    • @fwd8789
      @fwd8789 4 роки тому

      @@hvac_vdk О черт! А что, если PID 0 уже занят в этот момент?

    • @DmitryKetov
      @DmitryKetov  4 роки тому

      @@fwd8789 А 0 он не имеет смысла, поэтому не занят. Нет такого процесса, у которого pid=0

    • @fwd8789
      @fwd8789 4 роки тому

      @@DmitryKetov Спасибо

    • @fwd8789
      @fwd8789 4 роки тому

      @@DmitryKetov Стоп, а если форк присваивает PID=0, то как потом PID становится валидным идентификатором процесса? Кто его из нуля превращает в... заурядный номер процесса?