POSIX Threads

POSIX Threads — стандарт POSIX-реализации потоков (нитей) выполнения. Стандарт POSIX.1c, Threads extensions (IEEE Std 1003.1c-1995) определяет API для управления потоками, их синхронизации и планирования.

Реализации данного API существуют для большого числа UNIX-подобных ОС (GNU/Linux, Solaris, FreeBSD, OpenBSD, NetBSD, OS X), а также для Microsoft Windows и других ОС.

Библиотеки, реализующие этот стандарт (и функции этого стандарта), обычно называются Pthreads (функции имеют приставку «pthread_»).

Основные функции стандарта

Pthreads определяет набор типов и функций на языке программирования Си. Заголовочный файл — pthread.h.

  • Типы данных:
    • pthread_t: дескриптор потока;
    • pthread_attr_t: перечень атрибутов потока;
    • pthread_barrier_t: барьер;
    • pthread_barrierattr_t: атрибуты барьера;
    • pthread_cond_t: условная переменная;
    • pthread_condattr_t: атрибуты условной переменной;
    • pthread_key_t: данные, специфичные для потока;
    • pthread_mutex_t: мьютекс;
    • pthread_mutexattr_t: атрибуты мьютекса;
    • pthread_rwlock_t: мьютекс с возможностью эксклюзивной блокировки;
    • pthread_rwlockattr_t: атрибуты этого мьютекса;
    • pthread_spinlock_t: спинлок;
  • Функции управления потоками:
    • pthread_create(): создание потока.
    • pthread_exit(): завершение потока (должна вызываться функцией потока при завершении).
    • pthread_cancel(): отмена потока.
    • pthread_join(): подключиться к другому потоку и ожидать его завершения; поток, к которому необходимо подключиться, должен быть создан с возможностью подключения (PTHREAD_CREATE_JOINABLE).
    • pthread_detach(): отключиться от потока, сделав его при этом отдельным (PTHREAD_CREATE_DETACHED).
    • pthread_attr_init(): инициализировать структуру атрибутов потока.
    • pthread_attr_setdetachstate(): указывает параметр "отделимости" потока (detach state), который говорит о возможности подключения к нему (при помощи pthread_join) других потоков (значение PTHREAD_CREATE_JOINABLE) для ожидания окончания или о запрете подключения (значение PTHREAD_CREATE_DETACHED); ресурсы отдельного потока (PTHREAD_CREATE_DETACHED) при завершении автоматически освобождаются и возвращаются системе.
    • pthread_attr_destroy(): освободить память от структуры атрибутов потока (уничтожить дескриптор).
  • Функции синхронизации потоков:
    • pthread_mutex_init(), pthread_mutex_destroy(), pthread_mutex_lock(), pthread_mutex_trylock(), pthread_mutex_unlock(): с помощью мьютексов.
    • pthread_cond_init(), pthread_cond_signal(), pthread_cond_wait(): с помощью условных переменных.

Пример

Пример использования потоков на языке C:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>

void wait_thread (void);
void* thread_func (void*);

int main (int argc, char *argv[], char *envp[]) {
    pthread_t thread;
    if (pthread_create(&thread,NULL,thread_func,NULL)) return EXIT_FAILURE;
    for (unsigned int i = 0; i < 20; i++) {
        puts("a");
        wait_thread();
    }
    if (pthread_join(thread,NULL)) return EXIT_FAILURE;
    return EXIT_SUCCESS;
}

void wait_thread (void) {
    time_t start_time = time(NULL);
    while(time(NULL) == start_time) {}
}

void* thread_func (void* vptr_args) {
    for (unsigned int i = 0; i < 20; i++) {
        fputs("b\n",stderr);
        wait_thread();
    }
    return NULL;
}

Пример использования потоков на языке C++:

#include <cstdlib>
#include <iostream>
#include <memory>
#include <unistd.h>
#include <pthread.h>
    
class Thread {
public:
    int start () {
        return pthread_create( &_ThreadId, nullptr, Thread::thread_func, this );
    }
    int wait () {
        return pthread_join( _ThreadId, nullptr );
    }

protected:
    Thread() = default;
    Thread(const Thread&);

    virtual ~Thread () = default;
    virtual void run () = 0;

    static void* thread_func(void* d) {
        (static_cast <Thread*>(d))->run();
        return nullptr;
    }

private:
    pthread_t _ThreadId;
};

class TestingThread : public Thread {
public:
    TestingThread (const char* pcszText) : _pcszText( pcszText ) {}
    virtual void run () {
        for (unsigned int i = 0; i < 20; i++, usleep(1000)) std::cout << _pcszText << std::endl;
    }
protected:
    const char* _pcszText;
};

int main (int argc, char *argv[], char *envp[]) {
    TestingThread ThreadA("a");
    TestingThread ThreadB("b");
    return ThreadA.start() || ThreadB.start() || ThreadA.wait() || ThreadB.wait() ? EXIT_FAILURE : EXIT_SUCCESS;
}

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

Отличие состоит в том, что программа на C создаёт один новый поток для печати 'b', а основной поток печатает 'a'. Основной поток (после печати 'aaaaa….') ждёт завершения дочернего потока.

Программа на C++ создаёт два новых потока, один печатает 'a', второй, соответственно, — 'b'. Основной поток ждёт завершения обоих дочерних потоков.

См. также

Ссылки

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.