12.6.2. Функции POSIX: random() и srandom()
12.6.2. Функции POSIX: random() и srandom()
BSD 4.3 ввело random() и сопровождающие ее функции. Эти функции используют намного более подходящий генератор случайных чисел, который возвращает 31-разрядное значение. Теперь они входят в расширение XSI, стандартизованное POSIX:
#include <stdlib.h> /* XSI */
long random(void);
void srandom(unsigned int seed);
char *initstate(unsigned int seed, char *state, size_t n);
char *setstate(char *state);
Первые две функции близко соответствуют rand() и srand() и могут использоваться сходным образом. Однако, вместо одного начального значения, которое дает последовательность псевдослучайных чисел, эти функции используют начальное значение вместе с массивом состояния: массивом байтов, который хранит сведения о состоянии для вычисления псевдослучайных чисел. Последние две функции дают возможность управлять массивом состояния.
long random(void);
Возвращает число в диапазоне от 0 до 231-1. (Хотя справочная страница GNU/Linux random(3) говорит между 0 и RAND_MAX, это верно лишь для систем GLIBC, где RAND_MAX равен 231-1. На других системах RAND_MAX может быть меньше. POSIX явно называет диапазон от 0 до 231-1.)
void srandom(unsigned int seed);
Устанавливает начальное число. Если srandom() никогда не вызывается, по умолчанию используется 1.
char *initstate(unsigned int seed, char *state, size_t n);
Инициализирует массив state информацией для использования при генерации случайных чисел, seed является начальным значением, как для srandom(), а n является числом байтов в массиве state.
n должен равняться одному из значений 8, 32, 64, 128 или 256. Большие значения дают лучшие последовательности случайных чисел. Значения меньше 8 заставляют random() использовать простой генератор случайных чисел, сходный с rand(). Значения больше 8, не равные одному из значений в списке, округляются до ближайшего подходящего значения.
char *setstate(char *state);
Устанавливает внутреннее состояние в соответствии с массивом state, который должен быть инициализирован посредством initstate(). Это позволяет переключаться по желанию между различными состояниями, предоставляя множество генераторов случайных чисел.
Если initstate() и setstate() никогда не вызывались, random() использует массив внутреннего состояния размером 128.
Массив state непрозрачен; вы инициализируете его с помощью initstate() и передается функции random() посредством setstate(), но в другом отношении вам не нужно заглядывать в него. Если вы используете initstate() и setstate(). srandom() вызывать не нужно, поскольку начальное значение включено в информацию о состоянии. ch12-random.c использует эти процедуры вместо rand(). Используется также обычная методика, которая заключается в использовании в качестве начального значения генератора случайных чисел времени дня, добавленного к PID.
1 /* ch12-random.c --- генерация вращения костей с использованием random(). */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <sys/types.h>
6 #include <unistd.h>
7
8 char *die_faces[] = { /* Управляет ASCII графика! */
/* ... как раньше ... */
32 };
33
34 /* main --- выводит N различных граней кубиков */
35
36 int main(int argc, char **argv)
37 {
38 int nfaces;
39 int i, j, k;
40 char state[256];
41 time_t now;
42
/* ... проверка args, вычисление nfaces, как раньше ... */
55
56 (void)time(&now); /* В качестве начального значения используются время дня и PID */
57 (void) initstate((unsigned int)(now + getpid()), state, sizeof state);
58 (void)setstate(state);
59
60 for (i = 1; i <= nfaces; i++) {
61 j = random() % 6; /* использовать диапазон 0 <= j <= 5 */
62 printf("+-------+ ");
63 for (k = 0; k < 3; k++)
64 printf("|%s| ", die_faces[(j * 3) + k]);
65 printf("+-------+ ");
66 }
67
68 return 0;
69 }
Включение PID в состав начального значения гарантирует, что вы получите различные результаты, даже если две программы будут запушены в течение одной и той же секунды.
Поскольку она создает последовательности случайных чисел лучшего качества, random() является более предпочтительной по сравнению с rand(), и GNU/Linux и все современные системы Unix ее поддерживают.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
API, POSIX и библиотека С
API, POSIX и библиотека С Обычно прикладные программы не разрабатываются с непосредственным использованием системных вызовов, при этом используются программные интерфейсы приложений (Application Programing Interface, API). Это является важным, так как в таком случае нет необходимости в
POSIX (BSD) API
POSIX (BSD) API Эта часть API наиболее полно соответствует API ОС UNIX, относящихся к ветви BSD (BSD, FreeBSD, NetBSD и другие).[5] Ее наименование можно было бы сузить до «BSD API», так как описанный далее набор API System V также регламентируется POSIX, но мы будем использовать именно термин «POSIX API», следуя
IEEE и POSIX
IEEE и POSIX В 1980 году была создана инициативная группа под названием /usr/group с целью стандартизации программного интерфейса UNIX, т. е. формального определения услуг, предоставляемых операционной системой приложениям. Решение этой задачи упростило бы переносимость приложений
История POSIX
История POSIX Слово «POSIX» представляет собой сокращение от «Portable Operating System Interface» (интерфейс переносимой операционной системы). POSIX — целое семейство стандартов, разрабатываемых организацией IEEE (Institute of Electrical and Electronics Engineers — Институт инженеров по электротехнике и
7.8. Использование базы данных: random, генатом, найтивсе
7.8. Использование базы данных: random, генатом, найтивсе Во всех программах, которые рассматривались до сих пор, база данных использовалась лишь для хранения фактов и правил, с помощью которых определяются предикаты. Можно использовать базу данных и для хранения обычных
Posix
Posix Название Posix образовано от «Portable Operating System Interface», что означает приблизительно «интерфейс переносимых операционных систем». Это не один стандарт, а целое семейство, разработанное Институтом инженеров по электротехнике и радиоэлектронике (Institute for Electrical and Electronics Engineers
ГЛАВА 2 Posix IPC
ГЛАВА 2 Posix IPC 2.1. Введение Из имеющихся типов IPC следующие три могут быть отнесены к Posix IPC, то есть к методам взаимодействия процессов, соответствующим стандарту Posix:? очереди сообщений Posix (глава 5);? семафоры Posix (глава 10);? разделяемая память Posix (глава 13).Эти три вида IPC
Сигналы Posix: функции типа Async-Signal-Safe
Сигналы Posix: функции типа Async-Signal-Safe Недостаток пpoгрaммы из листинга 5.8 в том, что она вызывает mq_notify, mq_receive и printf из обработчика сигнала. Ни одну из этих функций вызывать оттуда не следует.Функции, которые могут быть вызваны из обработчика сигнала, относятся к группе,
Итераторы произвольного доступа (Random access iterators)
Итераторы произвольного доступа (Random access iterators) Класс или встроенный тип X удовлетворяет требованиям итераторов произвольного доступа, если к таблице, которая определяет двунаправленные итераторы, мы добавим следующие строки:Таблица 6: Требования итератора
Перетасовать (Random shuffle)
Перетасовать (Random shuffle) template ‹class RandomAccessIterator›void random_shuffle(RandomAccessIterator first, RandomAccessIterator last);template ‹class RandomAccessIterator, class RandomNumberGenerator›void random_shuffie(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rand);random_shuffle переставляет элементы в диапазоне [first, last) с равномерным распределением.
POSIX
POSIX В Linux и UNIX самый простой путь установления переменных окружения - добавить их определения в общесистемный профиль значений по умолчанию.Пользователь root также может:* выдать команды setenv() из командной строки wu командного скрипта;* для временного использования
POSIX
POSIX Linux, UNIX и другие платформы POSIX более предпочтительны, чем Windows, если требуется высокая безопасность. Технологии безопасности этих платформ являются продуманными и очень понятными в реализации. Безопасность файловой системы и надежный доступ присущи требованиям
9.6. $RANDOM: генерация псевдослучайных целых чисел
9.6. $RANDOM: генерация псевдослучайных целых чисел $RANDOM -- внутренняя функция Bash (не константа), которая возвращает псевдослучайные целые числа в диапазоне 0 - 32767. Функция $RANDOM не должна использоваться для генераци ключей
Пример 9-25. Имитация бросания кубика с помощью RANDOM
Пример 9-25. Имитация бросания кубика с помощью RANDOM #!/bin/bash# Случайные ли числа возвращает RANDOM?RANDOM=$$ # Инициализация генератора случайных чисел числом PID процесса-сценария.PIPS=6 # Кубик имеет 6 граней.MAXTHROWS=600 # Можете увеличить, если не знаете куда девать свое время.throw=0
Random’s Flash&Backup
Random’s Flash&Backup В качестве примера рассмотрим программу Random’s Flash&Backup. Эта сервисная программа для телефонов Motorola семейства P2K, созданная независимым разработчиком, демонстрирует все типичные основные возможности программ такого рода:• создание/восстановление