13 Keyfile.close();
14
15 while(TextFiles.empty())
16 { }
17
18 while(!TextFiles.empty())
19 {
20 pthread_mutex_lock(&QueueMutex);
21 Filename = TextFiles.front();
22 TextFiles.pop();
23 pthread_mutex_unlock(&QueueMutex);
24 Infile.open(Filename.c_str());
25 SearchWords.erase(SearchWords.begin(),SearchWords.end());
26
27 while(!Infile.eof() && Infile.good())
28 {
29 Infile >> Temp;
30 SearchWords.insert(Temp);
31 }
32
33 Infile.close();
34 if(includes(SearchWords.begin(),SearchWords.end(),
KeyWords.begin(),KeyWords.end(),Comp)){
35 Outfile << Filename << endl;
36 pthread_mutex_lock(&CountMutex);
37 FileCount--;
38 pthread_mutex_unlock(&CountMutex);
39 FoundCount++;
40 }
41 }
42 return(NULL);
43
44 }
Программа 4.7 содержит основной поток для потоков модели «изготовитель-потребитель», реализованных в программах 4.5 и 4.6.
// Программа 4.7
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8
9 pthread_mutex_t QueueMutex = PTHREAD_MUTEX_INITIALIZER;
10 pthread_mutex_t CountMutex = PTHREAD_MUTEX_INITIALIZER;
11
12 int FileCount = 0;
13 int FoundCount = 0;
14
15 int keySearch(void);
16 queue
17 set
18 set
19 ifstream Infile;
20 ofstream Outfile;
21 ifstream Keyfile;
22 string KeywordFile;
23 string OutFilename;
24 pthread_t Thread1;
25 pthread_t Thread2;
26
27 void depthFirstTraversal(const char *CurrentDir);
28 int isDirectory(string FileName);
29 int isRegular(string FileName);
30
31 int main(int argc, char *argv[])
32 {
33 if(argc != 4){
34 cerr << «need more info» << endl;
35 exit (1);
36 }
37
38 Outfile.open(argv[3],ios::app||ios::ate);
39 Keyfile.open(argv[2]);
40 pthread_create(&Thread1,NULL,task,argv[1]);
41 pthread_create(&Thread2,NULL,keySearch,argv[1]);
42 pthread_join(Thread1,NULL);
43 pthread_join(Thread2,NULL);
44 pthread_mutex_destroy(&CountMutex);
45 pthread_mutex_destroy(&QueueMutex);
46
47 cout << argv[1] << " contains " << FoundCount
<< " files that contains all keywords.» << endl;
48 return(0);
49 }
С помощью мьютексов доступ к разделяемой памяти для чтения или записи данных разрешается получить только одному потоку. Для гарантии безопасности работы функций, определенных пользователем, можно использовать и другие механизмы и методы, которые реализуют одну из моделей PRAM:
• EREW (монопольное чтение и монопольная запись)
• CREW (параллельное чтение и монопольная запись)
• ERCW (монопольное чтение и параллельная запись)
• CRCW (параллельное чтение и параллельная запись)
Мьютексы используются для реализации EREW-алгоритмов, которые рассматриваются в главе 5.
Безопасность использования потоков и библиотек
Климан (Klieman), Шах (Shah) и Смаалдерс (Smaalders) утверждали: