- •1. Введение
- •2. Многопоточное программирование
- •3.1. Example1: работа с памятью
- •3.1.1. Производительность
- •3.1.2. Масштабируемость
- •3.1.3. Масштабируемость Hyper-Threading архитектур
- •3.2. Example2.Exe: работа с файлами
- •4. Многопоточные программы
- •4.1. Mtftext.Exe: учебный пример
- •4.2. Mtcksrc.Exe: проверка исходного кода
- •If (tout.Size()) file(mp, fd::out).Write(tout);
- •4.3. Mtdel.Exe: удаление файлов
- •Вывод итоговой статистики, т.Е. Общего количества удаленных файлов и их совокупного размера.
- •Сообщение о возникших ошибках, как последнее сообщение программы.
- •4.4. Mtcnvsrc.Exe: конвертация исходного кода
- •4.5. Mtdirdiff.Exe: сравнение директорий
- •Mem_pool ownmp;
- •5. Библиотека derslib
- •6. Заключение
4.2. Mtcksrc.Exe: проверка исходного кода
Программа предназначена для рекурсивной проверки файлов исходного кода на соответствие следующим условиям:
все строки файла соответствуют DOS или UNIX формату
строки не содержат символов табуляции
длина строки не превышает 80 символов
отсутствуют пробелы в конце строки
Параметры командной строки: mtcksrc [-nt2] d|u mask[,mask2...]
[-ntN] |
количество потоков, 2 по умолчанию |
d |
проверять на соответствие DOS формату |
u |
проверять на соответствие UNIX формату |
mask[,mask2...] |
маски для поиска файлов, могут содержать * и ? символы |
Примеры использования: mtcksrc.exe u *.h,*.hpp,*.c,*.cpp mtcksrc.exe -nt1 d *.?pp
Несмотря на реальную полезность, текст программы практически не отличается от учебного примера mtftext. Единственное заметное отличие состоит в том, что сообщения о несоответствующих критериям строках не выводятся сразу же на экран, а собираются в один буфер для единовременного вывода в конце функции:
void MainTask::doCheckFile(mem_pool& mp, data_queue&, const CheckFileMsg& msg)
{
text_buf tout(mp);
file fin(mp, msg.fileName, file::rdo, 0);
buf_reader br(mp, fin, 64*1024);
sh_text line(nt(mp));
for (int num=1; br.read_line(line, false); num++) {
assert(line->size()>0);
if (line->back()=='\n') {
if (line->ends("\r\n")) {
if (!dos) tout+msg.fileName+':'+num+":dos\n";
line->uninitialized_resize(line->size()-2);
}
else {
if (dos) tout+msg.fileName+':'+num+":unix\n";
line->uninitialized_resize(line->size()-1);
}
}
if (line->find('\t')!=line->end()) tout+msg.fileName+':'+num+":tab\n";
if (line->size()>80) tout+msg.fileName+':'+num+":long "+line->size()+'\n';
if (line->size()>0 && line->back()==' ')
tout+msg.fileName+':'+num+":ending space\n";
}
If (tout.Size()) file(mp, fd::out).Write(tout);
}
В силу того, что файлы обрабатываются несколькими потоками одновременно, одновременно и независимо обнаруживаются и подходящие условиям строки, так что вывод их на экран без предварительного объединения в один, соответствующий всему файлу фрагмент, неудобен для пользователя. Если же необходимо получать упорядоченную не только по строкам, но и по файлам информацию (что очень полезно при первой проверке неряшливо написанного кода), то можно воспользоваться ключом -nt1, предписывающим однопоточную работу.
Ну, а теперь самое время проверить ваши собственные программы -- из-за пресловутого Copy/Paste DOS фрагменты не так уж и редко встречаются в UNIX файлах...
4.3. Mtdel.Exe: удаление файлов
Программа предназначена для рекурсивного удаления файлов по маскам.
Внимание! Удаление файлов зачастую приводит к безвозвратной потере данных, не запускайте эту программу из праздного любопытства!
Параметры командной строки: mtdel [-nt2] mask[,mask2...]
[-ntN] |
количество потоков, 2 по умолчанию |
mask[,mask2...] |
маски для поиска файлов, могут содержать * и ? символы |
Примеры использования: mtdel.exe *.obj,*.exe,*.res,out.???\* mtdel.exe -nt1 *.bak
Ну а эта программа, несмотря на кажущуюся простоту постановки задачи, является дальнейшим усложнением предыдущего примера. В процессе ее работы решаются следующие дополнительные задачи: