Лабораторная работа № 32. BOOST::THREADS. Многопоточное программирование 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Лабораторная работа № 32. BOOST::THREADS. Многопоточное программирование



Цель работы:

Овладеть навыками использования многопоточного программирования с использованием библиотеки BOOST.

Порядок выполнения работы

Решить задачи из [ Лабораторной работы № 23. Семафоры: защита критических секций, условная синхронизация ] с использованием библиотеки BOOST соответственно своему варианту.

 


BOOST::REGEX - РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ

Введение

Boost.Regex является собираемой библиотекой, т.е для ее использования необходимо ее собрать. Как это сделать написано в Getting started. Собирая библиотек вы можете выбрать один из двух алгоритмов, которые будет использоваться в движке регулярных выражений: рекурсивный и не-рекурсивный. Первый быстрый, но может грозить переполнением стека, второй немного медленней, но безопасный. Макросы для определения разных способов BOOST_REGEX_RECURSIVE и BOOST_REGEX_NON_RECURSIVE соответственно. Макросы для настройки алгоритмов и их описание можно посмотреть Здесь

Основные алгоритмы

boost::regex_match

Данный алгоритм используется для проверки соответсвия входящей строки и некоторого регулярного выражения, возвращая true Если строка соответсвует и false в другом случае. Типичный способ использования: regex_match(входящая_строка, [результаты_нахождения_соответствий], регулярное_выражение, [флаги]). Полный список всех перегруженных объявлений смотри в документации. Пример его использования:

std::string xStr("AAAA-12222-BBBBB-44455");

boost::regex xRegEx("(\\w+)-(\\d+)-(\\w+)-(\\d+)");

boost::smatch xResults;

std::cout << "================Results==================== \n";

std::cout << "Does this line match our needs? " << std::boolalpha << boost::regex_match(xStr, xResults, xRegEx) << "\n";

std::cout << "Print entire match:\n " << xResults[0] << std::endl;

std::cout << "Print the former string into another format:\n" << xResults[1] << "+" << xResults[2] << "+" << xResults[3] << "+" << xResults[4] << std::endl; * This source code was highlighted with Source Code Highlighter.

Результатом работы будет:

===================Results===========================

Does this line match our needs? true

Print entire match: AAAA-12222-BBBBB-44455

Print the former string into another format: AAAA+12222+BBBBB+44455

 

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

[Флаги] — необязательный параметр, с дефолтовым значением match_default. Про доступные флаги, можно посмотреть здесь. Флаги комбинируются посредством '|'(or).

Partial match

Частичное соответсвие необходимо для проверки входной строки, на частичное соответсвие регулярному выражению. Это может быть полезным при валидации поступающих асинхронно данных или при больших объемах данных, т.е в тех случаях когда в конкретный момент времени нет возможности провести полное соответсвие между регулярным выражением и исходной строкой. Чтобы использовать partial match, необходимо передать флаг match_partial в [флаги]. При этом, если используется частичное соответствие, то используемый алгоритм(regex_match, regex_search etc.) вернет true, но флаг matched у нулевого элеменат match_results будет уставновлен в false. То, что было найдено в результате частичного соответствия, можно получить через этот же нулевой элемент. Пример использования:

std::string xStr("AAAA-12222");

boost::regex xRegEx("(\\w+)-(\\d+)-(\\w+)-(\\d+)");

boost::smatch xResults;

std::cout << "===================Results================= \n";

std::cout << "Does this line match the regex? " << std::boolalpha << boost::regex_match(xStr, xResults, xRegEx, boost::match_default | boost::match_partial) << "\n";

std::cout << "Is it the partial match? " << std::boolalpha <<!xResults[0].matched << "\nPrint the partial match:\n" << xResults[0] << std::endl; * This source code was highlighted with Source Code Highlighter.

Вывод:

=====================Results=========================

Does this line match the regex? true

Is it the partial match? true

Print the partial match: AAAA-12222

 

regex_search

Данный алгоритм предназначен для поиска подстроки в исходной строке, по заданному регулярному выражению. Формат использования выглядит следующим образом: regex_search(входящая_строка, [результаты_нахождения_соответствий], регулярное_выражение, [флаги]). Пример использования:

std::string xStr("The boost library has a great opportunity for the regex!");

boost::regex xRegEx("\\b(?:\\w+?)((\\w)\\2)(?:\\w+?)\\b");

boost::smatch xResults;

std::cout << "==========================Results============================== \n";

std::string::const_iterator xItStart = xStr.begin();

std::string::const_iterator xItEnd = xStr.end();

while(boost::regex_search(xItStart, xItEnd, xResults, xRegEx))

{

std::cout << "Word, we've searched, is \"" << xResults[0] << "\". It has two \"" << xResults[2] << "\" inside itself.\n";

xItStart = xResults[1].second;

} * This source code was highlighted with Source Code Highlighter.

Вывод:

==========================Results============================== Word, we've searched, is «boost». It has two «o» inside itself. Word, we've searched, is «opportunity». It has two «p» inside itself.

 

regex_replace

Алгоритм используется для замены всех вхождений подстрок, соответсвующих регулярному выражению, на строку заданному в определенном формате. Результат может быть получен через итератор, переданный в качестве аргумента либо как возращаемая строка. Части сроки которые не соответствуют регулярному выражению, копируются в выходнуб строку не измененными, если не задан флаг format_no_copy, который оставляет только заматченные строки в результате. При переданном флаге format_first_only, заменяется только первая подстрока, соответствующая регулярному выражению. Типично используемый формат: regex_replace (входящая_строка, регулярное_выражение, форматная_строка, [флаги]). форматная_строка определяет строку, на которую будет заменятся найденная подстрока. Она может подчинятся одному из следующих правил синтаксиса:

· sed флаг:format_sed

· Perl(по умолчанию) флаг:format_perl

· Boost-extended флаг:format_all

· Литеральный, т.е не использует никаких специальных символов. Флаг:format_literal

Пример использования:

std::string xStr("AAAA-12222-BBBBB-44455");

boost::regex xRegEx("(\\w+)-(\\d+)-(\\w+)-(\\d+)");

std::string xFormatString("$1*$2*$3*$4");

boost::smatch xResults;

std::cout << "=================Results=================== \n";

std::cout << "Print string after replace:\n " << boost::regex_replace(xStr, xRegEx, xFormatString, boost::match_default | boost::format_perl) << std::endl; * This source code was highlighted with Source Code Highlighter.

Вывод:

====================Results===========================

Print string after replace: AAAA*12222*BBBBB*44455

 

Вспомогательные средства

regex_iterator

Данный итератор может быть удобен для последовательного поиска вхождений подстроки, соответствующей регулярному выражению. При каждом инкрементировании находится следующая подстрока, с помощью regex_search. При разыменовывании итератора мы получаем объект типа match_results, с помощью которого мы можем получить всю необходимую информацию. Формат использования: regex_iterator(начальный_итератор, конечный _итератор, регулярное_выражение) Пример использования:

std::string xStr("AAAA-12222-BBBBB-44455");

boost::regex xRegEx("(\\w|\\d)+");

boost::smatch xResults;

std::cout << "==========================Results============================== \n";

boost::sregex_iterator xIt(xStr.begin(), xStr.end(), xRegEx);

boost::sregex_iterator xInvalidIt;

while(xIt!= xInvalidIt)

std::cout << *xIt++ << "*";

* This source code was highlighted with Source Code Highlighter.

Вывод:

==========================Results==============================

AAAA*12222*BBBBB*44455*

 

regex_token_iterator

Очень полезный интрумент для разбиения строки на токены, Формат использования: regex_token_iterator(начальный_итератор, конечный _итератор, регулярное_выражение, [submatch]) [submatch] используется для указания, как следует интерпретировать токены в строке. При -1 итератор возвращает часть последовательности, которая не соответствует регулярному выражению. Т.е возвращается либо строка, которая идет после первого совпадения, до начала следующего совпадения(не включая первый символ совпадения). Либо, с начала строки, если начала строки не удовлетворяет регулярному выражению. Т.е при передаче -1, регулярное выражения является разделителем. При 0, каждое смещение итератора(++) дает следующую часть строки которая была “заматчена“, т.е каждый разыменованный итератор является capture строки. При любом положительном числе, в качестве параметра, выбирается capture регулярного выражения соответствующий числу, переданному в качестве параметра. Так же можно передать массив индексов в качестве параметра, тогда итератор будет искать каждый capture согласно индексам в массиве, т.е если массив состоит из {4, 2, 1}, тогда начальный итератор будет указывать на 4 capture, следующий итератор на 2 и т.д. Процесс будет повторятся для всей последовательности, пока не закончатся соответствия для данного регулярного выражения. По дефолту это параметр равен 0. Разыменованный итератор является объектом класса sub_match. Примеры использования:

std::string xStr("AAAA-12222-BBBBB-44455");

boost::regex xRegEx("(\\w|\\d)+");

boost::smatch xResults;

std::cout << "===================Results================ \n";

boost::sregex_token_iterator xItFull(xStr.begin(), xStr.end(), xRegEx, 0);

boost::sregex_token_iterator xInvalidIt;

std::cout << "Result the same as the regex_iterator: \n";

while(xItFull!= xInvalidIt)

std::cout << *xItFull++ << "*";

//Parts of captures

boost::regex xRegEx2("(\\w+)-(\\d+)");

boost::sregex_token_iterator xItFirstCapture(xStr.begin(), xStr.end(), xRegEx2, 1);

std::cout << "\nShow only first captures: \n";

while(xItFirstCapture!= xInvalidIt)

std::cout << *xItFirstCapture++ << "*";

//Reverse order

int aIndices[] = {2,1};

boost::sregex_token_iterator xItReverseCapture(xStr.begin(), xStr.end(), xRegEx2, aIndices);

std::cout << "\nShow captures in the reverse order: \n";

while(xItReverseCapture!= xInvalidIt) std::cout << *xItReverseCapture++ << "*"; //Delimiters

boost::regex xRegEx3("(\\w|\\d)+");

boost::sregex_token_iterator xItDelimiters(xStr.begin(), xStr.end(), xRegEx3, -1);

std::cout << "\nShow delimiters: \n";

while(xItDelimiters!= xInvalidIt)

std::cout << *xItDelimiters++ << " "; * This source code was highlighted with Source Code Highlighter.

Вывод:

=====================Results========================

Result the same as the regex_iterator: AAAA*12222*BBBBB*44455*

Show only first captures: AAAA*BBBBB*

Show captures in the reverse order: 12222*AAAA*44455*BBBBB*

Show delimiters: — — -

 

Замечание

Любой алгоритм может выбросить исключение типа std::runtime_error в случае если сложность проверки полного соответствия(matching) N элементов начнет превышать О(N^2) или в случае переполнения стека(если Boost.Regex был собран в рекурсивном режиме)

 



Поделиться:


Последнее изменение этой страницы: 2016-12-11; просмотров: 359; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.87.209.162 (0.03 с.)