QNX_book - страница 8

fd = shm_open("/swd_es", O_RDONLY, 0777); ако (fd == -1)

грешка ("shm_user"); връщане EXIT_FAILURE;

буфер = mmap(0, 100, PROT_READ, MAP_SHARED, fd, 0); ако (буфер == MAP_FAILED)

грешка ("shm_user"); връщане EXIT_FAILURE;

printf("shm_user: %s\n", буфер); munmap(буфер, sizeof(буфер)); връщане EXIT_SUCCESS;

към област от виртуалната памет на процеса, която може да се използва. Нека отпечатаме съдържанието на споделения обект:

printf("shm_user: %s\n", буфер);

По аналогия можем да прехвърляме всякакви структури от данни между процеси. Но не забравяйте, че вие ​​сте отговорни за правилната интерпретация на данните, съдържащи се в споделената памет.

Е, ако се сетихте да попитате: как процес, който чете данни от споделена памет, определя, че записът на данни вече е завършен и данните са готови за четене? Отговор: няма начин. За да избегнем нарушения на целостта на данните, трябва да използваме механизми

Основният механизъм за синхронизиране на процеса POSIX е

2.4.3. Други POSIX механизми

QNX Neutrino осигурява поддръжка за редица други механизми за синхронизация на POSIX и междупроцесна комуникация. Тези механизми включват именувани и неименувани семафори, POSIX опашки за съобщения. Няма да ги разглеждаме подробно, тъй като те са описани във всяка добра книга за UNIX.

Именуваният семафорен механизъм в QNX Neutrino се поддържа от мениджъра на ресурси mqueue (вижте глава 3).

Именуваните семафори се създават по следния начин: sem_t * mySem;

mySem = sem_open( "/my_semaphore", O_CREAT, 0777, 5);

Функцията sem_open() приема като аргумент името на семафора (в нашия случай /dev/sem/my_semaphore), флага за създаване на семафор,атрибути за достъп до семафор и стойност на брояча. Стойността на брояча указва броя на нишките, които могат да притежават семафора без блокиране.

Досега говорихме само за еднонишкови приложения, така че в този случай фразата "брой нишки" е еквивалентна на фразата "брой процеси". Ще говорим за нишките в глава 3.

Идеята е, че ако искаме да ограничим броя на нишките, работещи с даден ресурс, до 5, тогава създаваме семафор като този mySem. След това в програмата, преди да използваме защитения ресурс (например обект със споделена памет), трябва да извикаме функцията sem_wait(), като й предадем препратка към семафора:

Първите пет нишки, които успяха да извикат sem_wait(), ще продължат да работят гладко след извикването на тази функция, но останалите ще бъдат блокирани. Тези щастливи нишки, които са успели да се „промъкнат“, трябва да извикат функцията sem_post () след приключване на работата със защитения ресурс, което означава: „Едно място е освободено“. Коя от нишките, блокирани на семафора, ще бъде деблокирана? Този с най-висок приоритет. Ако приоритетите са еднакви, всяка нишка ще бъде деблокирана по преценка на Neutrino.

Но една лъжица е скъпа за вечеря. Възможно е дадена нишка да не трябва да бъде блокирана, докато чака семафорът да се отвори - тя може да "иска" да върши друга работа, докато ресурсът е зает. За такива случаи има функция sem_trywait() , която проверява дали семафорът е свободен и ако е свободен го изземва. В противен случай се връща със статус "заето" и нишката може да действа както си знае - няма да бъде блокирана.

Много значително предимство на наименуваните семафори е, че те могат да се използват за синхронизиране на процеси, изпълнявани на различни компютри в мрежа.

без имесемафорите в разпределените приложения по мрежата не ни помагат. Въпреки това, механизмът на неименуваните семафори (когато казват само „семафори“, те имат предвид точно тях) в QNX Neutrino се поддържа на ниво микроядро (вижте Глава 3).

За да създадете такъв семафор, използвайте функцията sem_init(), например:

sem_t * mySem; sem_init(mySem, 1, 5);

В този пример ще получим семафора, към който сочи указателят mySem с брой 5 (както в предишния пример). Моля, обърнете внимание на втория целочислен аргумент - 1 . Всъщност sem_init() прави разлика само между две стойности на този аргумент −

"нула" и "не-нула". Ако е зададен на 0, тогава семафорът може да се използва само за синхронизиране на нишки в рамките на един и същи процес. Ако е зададен на не-0, тогава семафорът може да бъде споделен с други процеси на хоста, използвайки механизма за споделена памет.

Използването на семафор без име е точно същото като използването на семафор с име.

POSIX опашки от съобщения

Опашките за съобщения POSIX се внедряват в Neutrino с помощта на мениджъра на ресурси mqueue, който вече познавате. За да използвате този механизъм от програмата, са предназначени функции, сред които са следните:

създаване/отваряне на опашка със съобщения — mq_open() ; изпращане на съобщение — mq_send() ;

получаване на съобщение — mq_recieve() .

Ако името на обекта започва с наклонена черта (/), когато е създадена опашката за POSIX съобщения, обектът ще бъде създаден в директорията /dev/mqueue. Размерът на файловия обект показва броя на съобщенията в опашката.

2.5. командни скриптове

Всички програми, стандартни и частни, които са част от операционната система и са достъпни чрез компютърна мрежа, могат да се комбинират по произволен начин сI/O пренасочване, тръбопроводи и други характеристики на обвивката. Ако трябва да се изпълнят множество команди, за да се изпълни задача, удобно е да напишете тези команди в текстов файл и след това да кажете на обвивката да "изпълни" този файл. Такъв файл се нарича команден скрипт (shell script - оттук и жаргонът "скрипт", или "shell скрипт"). По същество интерпретаторът имплементира език за програмиране от високо ниво. Използвайки този език, администраторите могат да управляват компютърната система (което по принцип правят).

Стартиране на скриптове за изпълнение

Тъй като shell е и език за програмиране, е редно да започнем да го усвояваме с известната програма „Hello world!“. Така че с помощта

ехо Здравей свят!

Обърнете внимание, че последният символ в командния скрипт трябва да е знак за нов ред. В крайна сметка, за да може интерпретаторът на черупката да изпълни команда, въведена в командния ред, трябва да натиснете клавиша, нали? Така че, когато някой скрипт не работи за вас, не бъдете твърде мързеливи, за да го проверите за наличието на знак за нов ред в края на файла - това помага на начинаещите програмисти на черупки в 50% от случаите ☺ .

Добре, но как ще изпълним скрипта? Знам поне четири начина да направя това:

стартирайте интерпретатора, като му дадете името на скрипт като аргумент или като асоциирате стандартния вход на интерпретатора със скрипт файл. Например:

стартирайте интерпретатора, като асоциирате стандартния вход на интерпретатора със скрипт файл. Например:

ш. на променлива A и на скрипта могат да се присвояват стойности

За да практикуваме, нека напишем script1.sh:

echo –n Входни променливи A, B и C: прочетете A B C

ехо A=$A ехо B=$B ехо C=$C

Тогаванаправете нашия скрипт изпълним и изпълнете: chmod a+x script1.sh

Когато бъдете подканени от скрипта Input variables A, B и C:, въведете низа 111 222 333 , като не забравяте да натиснете клавиша след това (няма да повтарям факта, че винаги трябва да натискате клавиша, за да изпълните команда или да въведете данни ☺ ).

На екрана ще видим следното:

Входни променливи A, B и C:111 222 333

Сега, като експеримент, стартирайте отново скрипта, но въведете реда 111 222 333 444 555 и вижте как се променя резултатът.

За да можете да използвате служебни знаци като част от низови променливи, се използва екраниране - обратна наклонена черта

Ако, да речем, на променлива A трябва да бъде присвоен низ $B като стойност, тогава това се прави по следния начин:

Тогава командата echo A=$A ще покаже: A=$B.

Вече обсъдихме, че променливите в обвивката са от тип низ, но обвивката предоставя някои удобства

което позволява променливите да се третират като цели числа. За това служи командата expr. Нека напишем script2.sh:

a=`expr $x + $y`; echo a=$a b=`expr $x - $y`; echo b=$b c=`expr $x / $y`; echo c=$c d=`expr $x "*" $y`; echo d=$d e=`expr $x % $y`; ехо e=$e

Нека стартираме този скрипт. На екрана получаваме: a=54

Обърнете внимание, че в резултат на разделянето получаваме само цялата част от резултата. Остатъкът от делението се получава с помощта на операцията %. Обърнете внимание също, че символът за умножение (звездичка - * ) е ограден в кавички, тъй като * е символ на обвивка, обозначаващ произволен низ.

Не забравяйте, че променливите и знаците на операциите трябва да бъдат разделени с интервали. Липсата на такива интервали е много често срещана грешка в програмирането на shell.

Всички променливи са налични само в процеса ksh, в койтокъдето са били декларирани (запомнете целта на командата точка). За да има достъп до променливи от процеси, които са деца на даден ksh процес, променливите трябва да бъдат "експортирани". Това може да стане по два начина. Първият е да създадете променлива и след това да я експортирате по всяко време:

Вторият начин е да експортирате променливата веднага след създаването: export VAR1=myvar

Можете да видите кои променливи на даден интерпретатор се експортират, като изпълните командата за експортиране без аргументи.

Всички променливи на обвивката (експортирани и неекспортирани) се отпечатват на екрана с командата set без аргументи.

Вътрешни променливи на Shell

Интерпретаторът на обвивката поддържа някои променливи, на които сам присвоява стойности (Таблица 2.1).

Таблица 2.1. Вътрешни променливи на интерпретатора

? Изходният код на последната команда (0 - нормален изход)

PID на текущия ksh процес

! PID на последния процес, работещ във фонов режим

# Брой параметри, предадени на обвивката

* Списък с опции на обвивката като един ред

@ Списък с параметри на Shell като колекция от думи

- Знамена, предадени на черупката

Разликата между $* и $@ е, че ако $* има стойност като "111 222 333", тогава $@ ще има стойност "111" "222" "333" .

Като всяка програма, скриптът може да приема аргументи. Малко по-рано, говорейки за вътрешни (вградени) променливи на обвивката, споменах променливи, съдържащи число и списък с параметри. Как да разчетем тези параметри? За тази цел обвивката поддържа специални променливи, чиито имена се състоят от една цифра в диапазона от 0 до 9. В този случай променливата 0 съдържа името на самия скрипт,променлива 1 е първият параметър, променлива 2 е вторият параметър и т. н. Както си спомняте, общият брой параметри се съдържа в променливата #.

Чудесно, но какво ще стане, ако изведнъж трябва да предадете, да речем, 30 аргумента към скрипта? За да прехвърлим нещо, разбира се, ще прехвърлим - не е чудно,

Калкулатор

Услуга за безплатна оценка на цената на работата

  1. Попълнете заявление. Експертите ще изчислят цената на вашата работа
  2. Изчисляването на цената ще дойде по пощата и SMS

Номерът на вашето приложение

Точно сега по пощата ще бъде изпратено автоматично писмо за потвърждение с информация за приложението.