RRDTHREADS(1) rrdtool RRDTHREADS(1)

rrdthreads - تمهیدات پیوند دادن کتابخانه RRD جهت استفاده در برنامه‌های چندنخی

استفاده از librrd در برنامه‌های چندنخی (multi-threaded) نیازمند برخی احتیاط‌های بیشتر است. این سند الزامات و دام‌های موجود در مسیر استفاده از librrd در برنامه‌هایتان را تشریح می‌کند. همچنین نکاتی را برای توسعهٔ آیندهٔ RRD جهت امن نگه‌داشتن کتابخانه در برابر نخ‌ها (thread-safe) ارائه می‌دهد.

از زمان RRDtool 1.6، کتابخانهٔ librrd امن در برابر نخ (thread-safe) است و نیازی به کتابخانهٔ جداگانهٔ مخصوص نخ نیست.

جهت استفاده از librrd در برنامه‌های چندنخی باید موارد زیر را رعایت کنید:

  • پیوند با librrd (هنگام پیوند دادن از "-lrrd" استفاده کنید)
  • استفاده از توابع «"_r"» به جای توابع عادی API
  • از هیچ‌گونه مشخصه زمانی به سبک at استفاده نکنید. تجزیهٔ چنین مشخصه‌های زمانی به هیچ وجه thread-safe نیست.
  • هرگز از توابع غیر *"_r" استفاده نکنید مگر اینکه در مستندات صراحتاً قید شده باشد که آن تابع thread-safe است.
  • هر نخ باید پیش از نخستین فراخوانی هر تابع "librrd"، تابع rrd_get_context() را جهت راه‌اندازی داده‌های مختص نخ فراخوانی کند. این کار کاملاً الزامی نیست، اما تنها راه برای آزمایش این است که آیا تخصیص حافظه توسط این تابع امکان‌پذیر است یا خیر. در غیر این صورت ممکن است برنامه در شرایط کمبود حافظه با یک SIGSEGV متوقف شود.
  • همیشه پیش از هر فراخوانی از کتابخانه، rrd_clear_error() را فراخوانی کنید. در غیر این صورت ممکن است فراخوانی به دلیل خطای قبلی با شکست مواجه شود.

از این پس در هنگام توسعهٔ RRD باید برخی موارد احتیاطی رعایت شود:

•
تنها از توابع thread-safe در کد کتابخانه استفاده کنید. بسیاری از توابع پرکاربرد libc امن در برابر نخ نیستند. در شرایط زیر یا هنگام استفاده از توابع کتابخانه‌ای زیر دقت فرمایید:
  • باید از فراخوانی مستقیم strerror() خودداری شود: به جای آن از rrd_strerror() استفاده کنید که یک پیام خطای اختصاصی برای هر نخ ارائه می‌دهد.
  • خانواده‌های توابع "getpw*"، "getgr*"، "gethost*" (و چند تابع "get*" دیگر) امن در برابر نخ نیستند: از گونه‌های *"_r" استفاده کنید
  • توابع زمان: "asctime"، "ctime"، "gmtime"، "localtime": از گونه‌های *"_r" استفاده کنید
  • "strtok": از "strtok_r" استفاده کنید
  • "tmpnam": از "tmpnam_r" استفاده کنید
  • بسیاری موارد دیگر (مستندات را بررسی کنید)
  • یک فایل سرآیند به نام rrd_is_thread_safe.h ارائه شده است که با پیش‌پردازندهٔ GNU C کار می‌کند تا برخی از رایج‌ترین توابع غیر thread-safe را با استفاده از دستورالعمل "#pragma GCC poison" اصطلاحاً «مسموم» (poison) کند. کافی است این سرآیند را در فایل‌های مبدایی که می‌خواهید thread-safe بمانند، بگنجانید.
  • متغیرهای سراسری تعریف نکنید!

    اگر واقعاً، واقعاً مجبور به استفاده از یک متغیر سراسری هستید، می‌توانید یک فیلد جدید به ساختار "rrd_context" بیفزایید و فایل‌های rrd_error.c، rrd_thread_safe.c و rrd_non_thread_safe.c را تغییر دهید.

  • در *"_r" از "getopt" یا "getopt_long" (نه به صورت مستقیم و نه غیرمستقیم) استفاده نکنید.

    تابع "getopt" از متغیرهای سراسری استفاده می‌کند و هنگام فراخوانی هم‌روند در یک برنامهٔ چندنخی، رفتار نادرستی از خود نشان می‌دهد. در عوض، یک تابع *_r ارائه دهید که تمام گزینه‌ها را به عنوان پارامترهای تابع دریافت کند. می‌توانید آرگومان‌های argc و **argv را برای فهرست‌های آرگومان با طول متغیر در نظر بگیرید. به عنوان نمونه به "rrd_update_r" نگاه کنید.

  • از تابع "rrd_parsetime" استفاده نکنید!

    این تابع از متغیرهای سراسری متعددی استفاده می‌کند. می‌توانید از آن در توابعی که برای thread-safe بودن طراحی نشده‌اند استفاده کنید، مانند توابعی که نسخهٔ "_r" یک عملیات را دربرمی‌گیرند (مانند "rrd_create"، اما نه در "rrd_create_r").

در حال حاضر گونه‌های thread-safe از "rrd_update"، "rrd_create"، "rrd_dump"، "rrd_info"، "rrd_last" و "rrd_fetch" وجود دارند.

Peter Stamfest <peter@stamfest.at>

2026-08-08 1.11.0