Статус нашего сайта: |
ICQ Information Center |
ICQ SHOP 5-значные 6-значные 7-значные 8-значные 9-значные Rippers List ОПЛАТА СТАТЬИ СЕКРЕТЫ HELP CENTER OWNED LIST РОЗЫСК!New! ICQ РЕЛИЗЫ Протоколы ICQ LOL ;-) Настройка компьютера Аватарки Смайлики СОФТ Mail Checkers Bruteforces ICQTeam Soft 8thWonder Soft Other Progs ICQ Patches Miranda ICQ ФорумАрхив! ВАШ АККАУНТ ICQ LiveJournal
РекламаНаш канал:irc.icqinfo.ru |
Таненбаум Э.- Архитектура компьютера. стр.358Рис. 6.22. Кольцевой буфер В листинге 6.1 показано решение задачи с производителем и потребителем на языке Java. Здесь имеется три класса: m, producer и consumer. Класс т содержит некоторые константы, указатели буфера in и out и сам буфер, который в нашем примере вмещает 100 простых чисел (от buffer[0] до buffer[99]). Для моделирования параллельных процессов в данном случае используются программные потоки (threads). У нас есть классы producer и consumer, которым приписываются значения переменных рис соответственно. Каждый из этих классов образуется из базового класса Thread. Метод run этого класса содержит код программного потока. Когда вызывается метод start для объекта, производного от класса Thread, запускается новый поток. Листинг 6-1- Параллельная работа в условиях гонок public class m { final public static int BUF_SIZE = 100; // буфер от 0 до 99 final public static long MAX_PRIME = 100000000000L; // остановиться здесь public static int in = 0, out = 0; // указатели на данные public static long buffer[ ] = new long[BUF_SIZE]; // числа хранятся здесь public static producer p; // имя производителя public static consumer с; // имя потребителя public static void main(String args[ ]){ // основной класс p = new producer ); // создание производителя с = new consumer ); // создание потребителя p.startO; // запуск производителя c.startO; // запуск потребителя } // Это утилита для циклического увеличения in и out public static int next(int k) { if (k < BUF_SIZE - 1) return(k + 1); else return(O); } } class producer extends Thread { // класс производителя public void run() { // код производителя long prime = 2; // временная переменная while (prime < m.MAX_PRIME) { prime = next_prime(prime); // оператор PI if (m.next(m.in) == m.out) suspendO; // оператор P2 m. buffer[m. in] = prime; // оператор P3 m.in = m.next(m.in); // оператор P4 if (m.next(m.out) == m.in) m.c.resumeO: // оператор P5 } } private long next_prime(long prime){ ... } // функция, вычисляющая // следующее число } class consumer extends Thread { // класс потребителя public void run() { // код потребителя long emirp = 2; // временная переменная while (emirp < m.MAX_PRIME) { if (m.in == m.out) suspendO; // оператор CI emirp = m.buffer[m.out]; // оператор C2 m.out = m.next(m.out); // оператор C3 if (m.out == m.nextdn.next(m.in))) m.p.resume(); // оператор C4 System.out.println(emirp); // оператор C5 } } } Каждый программный поток похож на процесс. Единственным отличием является то, что все потоки в пределах одной ^уа-программы находятся в едином адресном пространстве. Это позволяет им разделять один общий буфер. Если в компьютере имеется два и более процессора, каждый поток может выполняться на собственном процессоре, поэтому в данном случае имеет место реальный параллелизм. Если компьютер содержит только один процессор, потоки разделяются во времени на одном процессоре. Мы будем продолжать называть производителя и потребителя процессами (поскольку нас в данный момент интересуют параллельные процессы), хотя Java поддерживает параллелизм только на уровне программных потоков, а не «настоящих» процессов. |