Читаем UNIX: разработка сетевых приложений полностью

Могут не быть безопасными в многопоточной средеДолжны быть безопасными в многопоточной средеКомментарии
Asctimeasctime_rБезопасна в многопоточной среде только в случае непустого аргумента
ctermid
Ctimectime_r
getc_unlocked
getchar_unlocked
Getgridgetgrid_r
Getgrnamgetgrnam_r
Getlogingetlogin_r
Getpwnamgetpwnam_r
Getpwuidgetpwuid_r
Gmtimegmtime_r
Localtimelocaltime_r
putc_unlocked
putchar_unlocked
Randrand_r
Readdirreaddir_r
Strtockstrtock_r
tmpnamБезопасна в многопоточной среде только в случае непустого аргумента
Ttynamettyname_r
GethostXXX
GetnetXXX
GetprotoXXX
GetservXXX
inet_ntoa

Приведенная таблица позволяет заключить, что общим способом сделать функцию допускающей повторное вхождение является определение новой функции с названием, оканчивающимся на _r. Обе функции будут безопасными в многопоточной среде, только если вызывающий процесс выделяет в памяти место для результата и передает соответствующий указатель как аргумент функции.

<p>26.5. Собственные данные потоков</p>

При преобразовании существующих функций для использования в многопоточной среде часто возникают проблемы, связанные со статическими переменными. Функция, сохраняющая состояние в собственном буфере или возвращающая результат в виде указателя на статический буфер, не является безопасной в многопоточной среде, поскольку несколько потоков не могут использовать один и тот же буфер для хранения разных данных. Такая проблема имеет несколько решений.

1. Использование собственных данных потоков (thread-specific data). Это нетривиальная задача, и функция при этом преобразуется к такому виду, что может использоваться только в системах, поддерживающих потоки. Преимущество этого подхода заключается в том, что не меняется вызывающая последовательность, и все изменения связаны с библиотечной функцией, а не с приложениями, которые вызывают эту функцию. Позже в этом разделе мы покажем безопасную в многопоточной среде версию функции readline, созданную с применением собственных данных потоков.

2. Изменение вызывающей последовательности таким образом, чтобы вызывающий процесс упаковывал все аргументы в некую структуру, а также записывал в нее статические переменные из листинга 3.12. Это также было сделано, и в листинге 26.4 показана новая структура и новые прототипы функций.

Листинг 26.4. Структура данных и прототип функции для версии функции readline, допускающей повторное вхождение

typedef struct {

 int    read_fd;    /* дескриптор, указывающий, откуда считываются данные */

 char   *read_ptr;   /* буфер, куда передаются данные */

 size_t read_maxlen; /* максимальное количество байтов, которое может быть считано */

 /* следующие три элемента для внутреннего использования функцией */

 int    rl_cnt;      /* инициализируется нулем */

 char   *rl_bufptr;  /* инициализируется значением rl_buf */

 char   rl_buf[MAXLINE];

} Rline;

void readline_rinit(int, void*, size_t, Rline*);

ssize_t readline_r(Rline*);

ssize_t Readline_r(Rline*);

Эти новые функции могут использоваться как в системах с поддержкой потоков, так и в тех, где потоки не поддерживаются, но все приложения, вызывающие функцию readline, должны быть изменены.

3. Реструктуризация интерфейса для исключения статических переменных и обеспечения безопасности функции в многопоточной среде. Для readline это будет означать отказ от увеличения быстродействия, достигнутого в листинге 3.12, и возвращение к более старой версии, представленной в листинге 3.11. Поскольку мы назвали старую версию «ужасно медленной», это решение не всегда пригодно на практике.

Использование собственных данных потоков — это распространенный способ сделать существующую функцию безопасной в многопоточной среде. Прежде чем описывать функции Pthread, работающие с такими данными, мы опишем саму концепцию и возможный способ реализации, так как эти функции кажутся более сложными, чем являются на самом деле.

Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги