Титульная страница | Пространства имен | Алфавитный указатель | Классы | Файлы | Члены пространства имен | Члены классов | Описания | Примеры

sample/mrd_sem/main.cpp

/* threads_1: Multithreading support library Yauheni A. Akhotnikau (C) 2002-2003 eao197@yahoo.com ------------------------------------------------- Permission is granted to anyone to use this software for any purpose on any computer system, and to redistribute it freely, subject to the following restrictions: 1. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 2. The origin of this software must not be misrepresented, either by explicit claim or by omission. 3. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. ------------------------------------------------- */ /* Демострация работы mrd_sem_t. Стартуют несколько нитей читателей и нитей писателей. Каждая нить захватывает общий семафор в соответствующем режиме. Каждая нить отображает N строк при захваченом семафоре. После чего работа нити повторяется. */ #include <iostream> #include <string> #include <stdlib.h> #include <cpp_util_2/h/defs.hpp> #include <threads_1/h/threads.hpp> void show_str( const std::string & s ) { static threads_1::mutex_sem_t s_sem; // threads_1::mutex_sem_t::lock_t lock( s_sem ); std::cout << s << std::endl; } /* Базовый класс для нити. */ class sample_thread_t : public threads_1::thread_t { protected : // Синхронизирующий семафор. threads_1::mrd_sem_t & m_sem; // Имя нити. std::string m_name; // Количество циклов работы нити. unsigned int m_cycles; public : sample_thread_t( threads_1::mrd_sem_t & sem, const std::string & name, unsigned int cycles ); virtual ~sample_thread_t(); protected : // Данный метод выполняет все действия нити. virtual void body(); // Отвечает за захват семафора в нужном режиме. virtual void lock() = 0; // Отвечает за освобождение семафора. virtual void unlock(); }; sample_thread_t::sample_thread_t( threads_1::mrd_sem_t & sem, const std::string & name, unsigned int cycles ) : m_sem( sem ), m_name( name ), m_cycles( cycles ) { } sample_thread_t::~sample_thread_t() { } void sample_thread_t::body() { show_str( m_name + ": started" ); for( unsigned int i = 0; i != m_cycles; ++i ) { unsigned int n = 4 + rand() % 28; // Захватываем семафор и выполняем защищенную // часть работы. lock(); for( ; n; --n ) { show_str( m_name + ": protected string" ); threads_1::sleep_thread( 100 ); } unlock(); threads_1::sleep_thread( 100 ); } show_str( m_name + ": finished" ); } void sample_thread_t::unlock() { m_sem.release(); } /* Нить "читателя". */ class reader_thread_t : public sample_thread_t { public : reader_thread_t( threads_1::mrd_sem_t & sem, const std::string & name, unsigned int cycles ); virtual ~reader_thread_t(); protected : // Отвечает за захват семафора в нужном режиме. virtual void lock(); }; reader_thread_t::reader_thread_t( threads_1::mrd_sem_t & sem, const std::string & name, unsigned int cycles ) : sample_thread_t( sem, name, cycles ) { } reader_thread_t::~reader_thread_t() { } void reader_thread_t::lock() { m_sem.rd_lock(); } /* Нить "писателя". */ class writter_thread_t : public sample_thread_t { public : writter_thread_t( threads_1::mrd_sem_t & sem, const std::string & name, unsigned int cycles ); virtual ~writter_thread_t(); protected : // Отвечает за захват семафора в нужном режиме. virtual void lock(); }; writter_thread_t::writter_thread_t( threads_1::mrd_sem_t & sem, const std::string & name, unsigned int cycles ) : sample_thread_t( sem, name, cycles ) { } writter_thread_t::~writter_thread_t() { } void writter_thread_t::lock() { m_sem.wr_lock(); } int main() { // Синхронизирующий объект. threads_1::mrd_sem_t sem; // Захватываем его, чтобы тестовые нити не смогли // начать свою работу сразу после создания. sem.wr_lock(); reader_thread_t rd1( sem, "reader_1", 10 ); reader_thread_t rd2( sem, "reader_2", 10 ); reader_thread_t rd3( sem, "reader_3", 10 ); reader_thread_t rd4( sem, "reader_4", 10 ); reader_thread_t rd5( sem, "reader_5", 10 ); reader_thread_t rd6( sem, "reader_6", 10 ); writter_thread_t wr1( sem, "writter_1", 10 ); writter_thread_t wr2( sem, "writter_2", 10 ); // Запускаем все нити на работу. rd1.start(); rd2.start(); rd3.start(); rd4.start(); rd5.start(); rd6.start(); wr1.start(); wr2.start(); // Разрешаем работу тестовых нитей. sem.release(); // Ожидаем завершения работы нитей. rd1.wait(); rd2.wait(); rd3.wait(); rd4.wait(); rd5.wait(); rd6.wait(); wr1.wait(); wr2.wait(); return 0; }
00001 /* 00002 00003 threads_1: Multithreading support library 00004 Yauheni A. Akhotnikau (C) 2002-2003 00005 eao197@yahoo.com 00006 ------------------------------------------------- 00007 00008 Permission is granted to anyone to use this software for any purpose on any 00009 computer system, and to redistribute it freely, subject to the following 00010 restrictions: 00011 00012 1. This software is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00015 00016 2. The origin of this software must not be misrepresented, either by 00017 explicit claim or by omission. 00018 00019 3. Altered versions must be plainly marked as such, and must not be 00020 misrepresented as being the original software. 00021 00022 ------------------------------------------------- 00023 00024 */ 00025 /* 00026 Демострация работы mrd_sem_t. 00027 00028 Стартуют несколько нитей читателей и нитей писателей. 00029 Каждая нить захватывает общий семафор в соответствующем 00030 режиме. Каждая нить отображает N строк при захваченом 00031 семафоре. После чего работа нити повторяется. 00032 */ 00033 00034 #include <iostream> 00035 #include <string> 00036 00037 #include <stdlib.h> 00038 00039 #include <cpp_util_2/h/defs.hpp> 00040 00041 #include <threads_1/h/threads.hpp> 00042 00043 void 00044 show_str( const std::string & s ) 00045 { 00046 static threads_1::mutex_sem_t s_sem; 00047 00048 // threads_1::mutex_sem_t::lock_t lock( s_sem ); 00049 std::cout << s << std::endl; 00050 } 00051 00052 /* 00053 Базовый класс для нити. 00054 */ 00055 class sample_thread_t : 00056 public threads_1::thread_t 00057 { 00058 protected : 00059 // Синхронизирующий семафор. 00060 threads_1::mrd_sem_t & m_sem; 00061 00062 // Имя нити. 00063 std::string m_name; 00064 00065 // Количество циклов работы нити. 00066 unsigned int m_cycles; 00067 00068 public : 00069 sample_thread_t( 00070 threads_1::mrd_sem_t & sem, 00071 const std::string & name, 00072 unsigned int cycles ); 00073 virtual ~sample_thread_t(); 00074 00075 protected : 00076 // Данный метод выполняет все действия нити. 00077 virtual void 00078 body(); 00079 00080 // Отвечает за захват семафора в нужном режиме. 00081 virtual void 00082 lock() = 0; 00083 00084 // Отвечает за освобождение семафора. 00085 virtual void 00086 unlock(); 00087 }; 00088 00089 sample_thread_t::sample_thread_t( 00090 threads_1::mrd_sem_t & sem, 00091 const std::string & name, 00092 unsigned int cycles ) 00093 : 00094 m_sem( sem ), 00095 m_name( name ), 00096 m_cycles( cycles ) 00097 { 00098 } 00099 00100 sample_thread_t::~sample_thread_t() 00101 { 00102 } 00103 00104 void 00105 sample_thread_t::body() 00106 { 00107 show_str( m_name + ": started" ); 00108 00109 for( unsigned int i = 0; i != m_cycles; ++i ) 00110 { 00111 unsigned int n = 4 + rand() % 28; 00112 00113 // Захватываем семафор и выполняем защищенную 00114 // часть работы. 00115 lock(); 00116 for( ; n; --n ) 00117 { 00118 show_str( m_name + ": protected string" ); 00119 threads_1::sleep_thread( 100 ); 00120 } 00121 unlock(); 00122 threads_1::sleep_thread( 100 ); 00123 } 00124 00125 show_str( m_name + ": finished" ); 00126 } 00127 00128 void 00129 sample_thread_t::unlock() 00130 { 00131 m_sem.release(); 00132 } 00133 00134 /* 00135 Нить "читателя". 00136 */ 00137 class reader_thread_t : 00138 public sample_thread_t 00139 { 00140 public : 00141 reader_thread_t( 00142 threads_1::mrd_sem_t & sem, 00143 const std::string & name, 00144 unsigned int cycles ); 00145 virtual ~reader_thread_t(); 00146 00147 protected : 00148 // Отвечает за захват семафора в нужном режиме. 00149 virtual void 00150 lock(); 00151 }; 00152 00153 reader_thread_t::reader_thread_t( 00154 threads_1::mrd_sem_t & sem, 00155 const std::string & name, 00156 unsigned int cycles ) 00157 : 00158 sample_thread_t( sem, name, cycles ) 00159 { 00160 } 00161 00162 reader_thread_t::~reader_thread_t() 00163 { 00164 } 00165 00166 void 00167 reader_thread_t::lock() 00168 { 00169 m_sem.rd_lock(); 00170 } 00171 00172 /* 00173 Нить "писателя". 00174 */ 00175 class writter_thread_t : 00176 public sample_thread_t 00177 { 00178 public : 00179 writter_thread_t( 00180 threads_1::mrd_sem_t & sem, 00181 const std::string & name, 00182 unsigned int cycles ); 00183 virtual ~writter_thread_t(); 00184 00185 protected : 00186 // Отвечает за захват семафора в нужном режиме. 00187 virtual void 00188 lock(); 00189 }; 00190 00191 writter_thread_t::writter_thread_t( 00192 threads_1::mrd_sem_t & sem, 00193 const std::string & name, 00194 unsigned int cycles ) 00195 : 00196 sample_thread_t( sem, name, cycles ) 00197 { 00198 } 00199 00200 writter_thread_t::~writter_thread_t() 00201 { 00202 } 00203 00204 void 00205 writter_thread_t::lock() 00206 { 00207 m_sem.wr_lock(); 00208 } 00209 00210 00211 int 00212 main() 00213 { 00214 // Синхронизирующий объект. 00215 threads_1::mrd_sem_t sem; 00216 // Захватываем его, чтобы тестовые нити не смогли 00217 // начать свою работу сразу после создания. 00218 sem.wr_lock(); 00219 00220 reader_thread_t rd1( sem, "reader_1", 10 ); 00221 reader_thread_t rd2( sem, "reader_2", 10 ); 00222 reader_thread_t rd3( sem, "reader_3", 10 ); 00223 reader_thread_t rd4( sem, "reader_4", 10 ); 00224 reader_thread_t rd5( sem, "reader_5", 10 ); 00225 reader_thread_t rd6( sem, "reader_6", 10 ); 00226 00227 writter_thread_t wr1( sem, "writter_1", 10 ); 00228 writter_thread_t wr2( sem, "writter_2", 10 ); 00229 00230 // Запускаем все нити на работу. 00231 rd1.start(); 00232 rd2.start(); 00233 rd3.start(); 00234 rd4.start(); 00235 rd5.start(); 00236 rd6.start(); 00237 00238 wr1.start(); 00239 wr2.start(); 00240 00241 // Разрешаем работу тестовых нитей. 00242 sem.release(); 00243 00244 // Ожидаем завершения работы нитей. 00245 rd1.wait(); 00246 rd2.wait(); 00247 rd3.wait(); 00248 rd4.wait(); 00249 rd5.wait(); 00250 rd6.wait(); 00251 wr1.wait(); 00252 wr2.wait(); 00253 00254 return 0; 00255 }

Документация по threads_1. Последние изменения: Wed Aug 4 06:46:00 2004. Создано системой doxygen 1.3.7
Hosted by uCoz