У меня есть два файла c: производитель.с и потребитель.с. Потребитель создает общий буфер в памяти и ждет, когда производитель поместит элементы в буфер для потребления. Производитель прикрепляет разделяемую память к своей карте памяти, а затем начинает помещать элементы в буфер.
Вопрос в том, как скомпилировать и запустить их вместе?
Вот собственно задание. (Я знаю, что могу сделать это с одним файлом c, используя потоки, но меня об этом не просят.)
В этой части вы разработаете приложение производитель-потребитель, которое будет использовать общую память для взаимодействия процессов (общая память POSIX, а не общая память System V). Будет N производителей и N потребителей. N может быть 1, 2 или 3.
Вы разработаете программу-производителя (producer.c) и программу-потребителя (consumer.c). При запуске программа-производитель создаст N дочерних процессов, которые будут действовать как N производителей (т. е. каждый дочерний процесс будет процессом-производителем).
Точно так же при запуске программа-потребитель создаст N дочерних процессов, где каждый дочерний процесс будет действовать как процесс-потребитель. Вы будете считать, что потребители идентифицируются как 0, 1, 2, в зависимости от N. Например, если N равно 2, то будет два потребителя, 0 и 1.
Сначала будет запущена потребительская программа. При запуске программа-потребитель сначала создаст разделяемую память размером 4 КБ. Эта общая память будет местом, где у вас будет общий общий буфер. К буферу могут обращаться производители и потребители. Размер буфера равен 100. Он может содержать не более 100 элементов (целых чисел). В общей памяти вы можете иметь некоторые другие общие переменные, которые вы считаете необходимыми. Программа-потребитель также создаст один или несколько семафоров (количество решаете вы сами).
Затем он создаст N дочерних процессов (N потребителей) с помощью системного вызова fork() (вам не нужно будет использовать системный вызов exec()). Основной процесс программы-потребителя (родительский) после создания дочерних процессов не должен завершаться. Он должен ждать, пока все дети (т.е. потребители) закончат свои задачи и завершатся. Когда все дети завершатся, он удалит (удалит) общую память из системы. Он также удалит (удалит) семафоры. Тогда и он может прекратиться.
Каждый производитель будет читать входной файл с положительными целыми числами (по одному целому числу в строке) и просто передавать целые числа через общий буфер, находящийся в общей памяти (созданной программой-потребителем) между производителями и потребителями.
Каждый потребитель будет считывать целые числа из общего буфера и записывать полученное целое число z в выходной файл, связанный с потребителем, если z mod N равен идентификатору потребителя. Например, если N равно 3 и если идентификатор потребителя равен 2, а потребитель получил целое число 7, он ничего с ним не сделает (проигнорирует), но если он получит 8, он запишет целое число в свой выходной файл. . Выходной файл будет содержать одно целое число в строке. Пока производители и потребители обращаются к общему буферу, они должны использовать семафоры, чтобы доступ был синхронизирован. Кроме того, если буфер заполнен, производители должны спать, а если нечего потреблять, потребители должны спать. Мы не должны быть заняты ожиданием. Вы будете использовать семафоры POSIX (именованные семафоры). Программа потребителя будет вызвана следующим образом:
потребитель N …Здесь N — количество создаваемых процессов-потребителей. Значение этого параметра должно совпадать с соответствующим параметром программы-производителя. Здесь — это имя выходного файла, который будет использоваться потребителем с идентификатором X. Количество введенных имен выходных файлов будет равно N. — это имя, которое мы можем использовать для идентификации общей памяти. это имя, которое мы можем использовать для идентификации семафоров (это может быть префикс, который можно использовать для имен многих семафоров). Эти же имена должны использоваться при вызове производителя. Программа производителя будет называться производителем и будет вызываться со следующими параметрами:
производитель N …Здесь N — количество производителей. Это имя входного файла для производителя X. Входной файл — это текстовый файл, в котором хранятся целые числа. Количество вводимых нами имен входных файлов будет равно N. В файле может быть одно или несколько целых чисел. Входной файл может быть довольно большим (миллиарды целых чисел). это имя, которое мы можем использовать для идентификации разделяемой памяти. это имя, которое мы можем использовать для идентификации семафоров.
Пример вызова программ может быть следующим: