ریسه‌های پازیکس

ریسه‌های پازیکس  (یا به اختصار pthreads) اشاره به تعدادی رابط برنامه‌نویسی نرم‌افزار در استاندارد پازیکس دارد که برای کار با ریسه‌ها در نظر گرفته شده‌اند.در سیستم‌عامل‌های سازگار با این استاندارد مانند فری‌بی‌اس‌دی، اپن‌بی‌اس‌دی، نت‌بی‌اس‌دی، لینوکس، سولاریس و ...، پیاده‌سازی‌های مختلفی از این رابط‌های برنامه‌نویسی وجود دارد. این رابط‌های برنامه‌نویسی در یک فایل سرآیند به نام pthreads.h تعریف شده‌اند. این فایل حاوی تعداد تابع، نوع داده و تعدادی ثوابت است. حدوداً صد عدد روال مختلف برای کار با ریسه‌ها فراهم شده که نام تمام آنها با pthread_ شروع می‌شود. این روال‌ها را می‌توان به چهار دسته تقسیم کرد:
 مدیریت ریسه‌ها - ایجاد، اتصال و ...
 mutex ها
 متغیرهای شرطی
 همگام‌سازی

مثال 
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define NUM_THREADS     5

void *TaskCode(void *argument)
{
   int tid;

   tid = *((int *) argument);
   printf("Hello World! It's me, thread %d!\n", tid);

   /* optionally: insert more useful stuff here */

   return NULL;
}

int main(void)
{
   pthread_t threads[NUM_THREADS];
   int thread_args[NUM_THREADS];
   int rc, i;

   /* create all threads */
   for (i=0; i<NUM_THREADS; ++i) {
      thread_args[i] = i;
      printf("In main: creating thread %d\n", i);
      rc = pthread_create(&threads[i], NULL, TaskCode, (void *) &thread_args[i]);
      assert(0 == rc);
   }

   /* wait for all threads to complete */
   for (i=0; i<NUM_THREADS; ++i) {
      rc = pthread_join(threads[i], NULL);
      assert(0 == rc);
   }

   exit(EXIT_SUCCESS);
}
این برنامه پنج ریسه ایجاد کرده که هر کدام با صدا زدن تابعی به نام TaskCode شماره منحصربه‌فرد هر ریسه را در خروجی استاندارد چاپ می‌کنند. برای کامپایل این برنامه، کامپایلر باید با پارامتر -pthread فراخوانی شود.

توابع 
بیشتر از ۱۰۰ تابع برای کار با ریسه‌ها در نظر گرفته شده است.  نوع pthread_t برای نگه‌داری شماره ID ریسه مورد نظر استفاده می‌شود. نوع pthread_mutex_t هم برای برقراری انحصار متقابل و استفاده از mutex ها استفاده می‌شود.

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
	     void *(*start_routine)(void *), void *arg)

این رویه یک ریسه جدید ایجاد می‌کند. thread اشاره‌گری به یک ساختمان pthread_t است که TID ریسه مورد نظر در آن قرار خواهد گرفت. attr ویژگی‌های ریسه را مشخص می‌کند. برای استفاده از صفات پیشرفض می‌توان به جای آن NULL قرار داد. start_routine اشاره گر به تابعی است که به محض اجرای شدن ریسه فراخوانی می‌شود. این تابع یک آرگومان void* دریافت می‌کند و مقدار برگشتی آن هم از همین نوع است. arg آرگومان این تابع را مشخص می‌کند.

int pthread_equal(pthread_t t1, pthread_t t2)

این تابع ریسه‌های t1 و t2 را با هم مقایسه می‌کند. اگر برابر بودند، یک مقدار  غیر صفر برمی‌گردد.

void pthread_exit(void *value_ptr)

فراخوانی این تابع توسط یک ریسه، باعث می‌شود اجرای آن ریسه خاتمه یابد. value_ptr مقدار برگشتی ریسه است. این مقدار در تابع pthread_join در دسترس قرار می‌گیرد.

int pthread_join(pthread_t thread, void **value_ptr)

فراخوانی این تابع باعث می‌شود تا ریسه فراخوان، منتظر بماند تا threadبه کار خود پایان دهد. وقتی که آن ریسه به کار خود پایان داد، مقدار برگشتی‌اش در value_ptr قرار می‌گیرد.

int pthread_kill(pthread_t thread, int sig)

این تابع سیگنال sig را به ریسه thread ارسال می‌کند.

pthread_t pthread_self(void)

شماره ID ریسه فراخوان را برمی‌گرداند.

void pthread_yield(void)

به زمانبند سیستم اجازه می‌دهد تا ریسه دیگری را برای اجرا شدن انتخاب کند.

int pthread_mutex_init(pthread_mutex_t *mutex,
	     const pthread_mutexattr_t *attr)

mutex را برای استفاده کردن آماده می‌کند. قبل از استفاده از mutex، باید این تابع بر روی آن قراخوانی شود. attr صفات آن mutex است. می‌تواند NULL باشد تا از ضفات پیشفرض استفاده شود.

int pthread_mutex_lock(pthread_mutex_t *mutex)

پس از مرحله آماده‌سازی، می‌توان این تابع را بر روی mutex فراخوانی کرد تا mutex قفل شود. این کار دقیقاً قبل از ورود به ناحیه بحرانی و استفاده از منبع مشترک صورت می‌گیرد.

int pthread_mutex_unlock(pthread_mutex_t *mutex)

mutex را باز می‌کند. پس از اینکه ریسه از منبع مشترک استفاده کرد، باید این تابع را بر روی mutex فراخوانی کند تا بقیه ریسه‌ها بتوانند از آن استفاده کنند.

int pthread_mutex_destroy(pthread_mutex_t *mutex)

پس از اتمام کار با mutex باید این تابع روی آن فراخوانی شود تا mutex نابود شود. با نابود شدن mutex، دیگر نمی‌توان از آن استفاده کرد.

برای مطالعه بیشتر

پیوند به بیرون 

 Pthreads Tutorial
 C/C++ Tutorial: using Pthreads
 Article "POSIX threads explained" by دنیل رابینز
 Interview "Ten Questions with David Butenhof about Parallel Programming and POSIX Threads" by Michael Suess
 Open Source POSIX Threads for Win32 
 The Open Group Base Specifications Issue 6, IEEE Std 1003.1
 Pthreads Presentation at 2007 OSCON (O'Reilly Open Source Convention) by Adrien Lamothe. An overview of Pthreads with current trends. 
 Comparing programmability of Open MP and pthreads

منابع 

رایانش موازی
ریسه‌ها (رایانش)
کتابخانه پازیکس سی