Статус
нашего
сайта:
ICQ Secrets Center is Online  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


Таненбаум Э.- Архитектура компьютера. стр.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 поддерживает параллелизм только на уровне программных потоков, а не «настоящих» процессов.


⇐ Предыдущая страница| |Следующая страница ⇒

.