English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
تطبيقات محول التوقيت Timer واسعة النطاق، في نظام Linux، هناك عدة طرق:
1، باستخدام sleep() وusleep()
بينما دقة النوم هي 1 ثانية، دقة usleep هي 1 ميكرو ثانية، لا يتم كتابة الكود المحدد. يوجد عيب واضح في هذا الأسلوب، في نظام Linux، لا يمكن التأكد من دقة وظائف النوم، خاصة عندما يكون تحميل النظام كبيرًا، حيث يكون هناك عادةً ظاهرة تجاوز المدة المحددة.
2، باستخدام إشارة SIGALRM + alarm()
دقة هذا الأسلوب تصل إلى 1 ثانية، حيث يستخدم نظام النوافذ النجمية ميكانيكية الإشارات، أولاً يتم تسجيل معالج إشارة SIGALRM، يتم استدعاء alarm()، لتحديد طول الجلسة، كما يلي:
#include <stdio.h> #include <signal.h> void timer(int sig) { إذا (SIGALRM == sig) { printf("timer\n"); alarm(1); //نستمر في إعداد闹钟 } return ; } int main() { signal(SIGALRM, timer); //ربط الإشارة والوظيفة alarm(1); //إطلاق闹钟 getchar(); return 0; }
الطريقة alarm جيدة جدًا، ولكن لا يمكن أن تكون دقيقة أقل من 1 ثانية.
استخدام RTC mechanism الثالث
استخدام RTC mechanism باستخدام وحدة Real Time Clock المقدمة من معالج النظام، من خلال قراءة RTC hardware /dev/rtc، من خلال ioctl() لتعيين تردد RTC، الكود كما يلي:
#include <stdio.h> #include <linux/rtc.h> #include <sys/ioctl.h> #include <sys/time.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> int main(int argc, char* argv[]) { unsigned long i = 0; unsigned long data = 0; int retval = 0; int fd = open("/dev/rtc", O_RDONLY); if(fd < 0) { perror("open"); exit(errno); } /*ضبط التردد على 4Hz*/ if(ioctl(fd, RTC_IRQP_SET, 1) < 0) { perror("ioctl(RTC_IRQP_SET)"); close(fd); exit(errno); } /* تشغيل التinterrupts الدورية */ if(ioctl(fd, RTC_PIE_ON, 0) < 0) { perror("ioctl(RTC_PIE_ON)"); close(fd); exit(errno); } for(i = 0; i < 100; i++) { if(read(fd, &data, sizeof(unsigned long)) < 0) { perror("read"); close(fd); exit(errno); } printf("timer\n"); } /* إيقاف التerruptات الدورية */ ioctl(fd, RTC_PIE_OFF, 0); close(fd); return 0; }
هذا الطريقة سهلة الاستخدام، تستخدم وحدة RTC المقدمة من معالج النظام، ودقة قابلة للتعديل، وهي مرتفعة جدًا.
4،استخدام select()
هذه الطريقة راحلتها في كتاب APUE، الطريقة غير شائعة، حيث يتم استخدام select() لضبط定时器؛ يُستخدم المبدأ للخامس parameter في method select()، حيث يتم تعيين الأول parameter إلى 0، وكل ثلاثة مجموعات من descriptors مُعدلة إلى NULL، والخامس parameter هو structure time، والكود كما يلي:
#include <sys/time.h> #include <sys/select.h> #include <time.h> #include <stdio.h> /*seconds: the seconds; mseconds: the micro seconds*/ void setTimer(int seconds, int mseconds) { struct timeval temp; temp.tv_sec = seconds; temp.tv_usec = mseconds; select(0, NULL, NULL, NULL, &temp); printf("timer\n"); return ; } int main() { int i; for(i = 0 ; i < 100; i++) setTimer(1, 0); return 0; }
يمكن لهذه الطريقة الوصول إلى مستوى دقة الميكرو ثانية، هناك العديد من定时器的 multi-threading القائمين على select()، مما يعني أن استقرار select() جيد جدًا.
النهاية:إذا كانت متطلبات النظام منخفضة، يمكن النظر في استخدام sleep() البسيط، لأن سطرًا واحدًا يمكنه حل المشكلة؛ إذا كانت متطلبات الدقة مرتفعة، يمكن النظر في استخدام RTC mechanism و mechanism select().
وهذا هو تلخيص الكاتب لكيفية تنفيذ Timer في Linux بطرق متعددة، نأمل أن تحصلوا على الدعم والهتاف لتعليماتنا~