Jiffy Nedir ?
time(7) sayfasında yazdığına göre iki çeşit saat var. Bunlar Software clock ve Hardware clock.
Software clock jiffies cinsinden ölçüm yapıyor. Jiffy Linux'ta sistem açıldığından beri geçen software tickleri gösterir. Linux 2.6 çekirdeğinden itibaren bir jiffy ticki 0.004 saniyeye eşit. (4 mili saniye).
Bir çok sistem çağrısı (sleep, select gibi) software clock ile çalıştığı için her zaman tam istenilen çözünürlüğü sağlamayabilirler.
Hardware clock ise direkt donanım kesmesine bağlı olduğu için çok daha hassatır. Burada donanıma bağlı olan Time Stamp Counter değerini rdtsc komutu ile okuma örneği bulunuyor.
Sleep ve Gerçek Zamanlı Olmayan İşletim Sistemleri
Gerçek zamanlı olmayan işletim sistemlerinde herhangi bir sleep türevi uygulamayı tam istenilen zamanda uyandırmayı garanti etmez!. Aşağıdaki şekilde durum görülebilir.
High-resolution timers
Diğer timerlara göre çok daha yüksek çözünürlük imkanı sağlarlar. High resolution timer'lar jiffy ile kısıtlanmazlar.
Windows
1. Sleep
#include <window.h> yapıldıktan sonra Sleep() metodu ile milisaniye kadar uyumak mümkün.
2. WaitableTimer
Sleep()'ten daha hassas bir zaman kullanabilmemizi sağlar. Zaman 100 nanosaniye çözünürlüğündedir.
POSIX metodları
1. nanosleep() - Bir sinyal tarafından yarıda kesilebilir
Metodun imzası şöyle
2. clock_nanosleep()
Metodun imzası şöyle
Örneğin 0.5 milisaniye uyumak için şöyle yaparız.
Aşağıdaki kodda şimdiki zaman alınıp, sonra mutlak zaman hesaplandığı için yukarıdaki örnek ile aynı kapıya çıkar.
3. usleep() - Bir sinyal tarafından yarıda kesilirse kalan süreyi alma imkanı yok
usleep() mikrosaniye (saniyenin milyonda biri) cinsinden bir süre verilerek kullanılabiliyor. nanosleep()'ten farklı olarak yarıda kesilirse kalan süreyi alabilme seçeneği yok. Şöyle kodlarız.
4. sleep() - Bir sinyal tarafından yarıda kesilebilir
sleep() saniye cinsinden bir süre verilerek kullanılabiliyor. Eğer 0'dan farklı bir değer dönerse, metod yarıda kesilmiştir ve kalan süreyi belirtir.
sleep (0) yield ile aynı anlama gelir. Yani thread çalışmak için süresi varsa bile, süresinden feragat eder.
5. select
select ile mikrosaniye cinsinden uyuma yapmak ta mümkün. Hatta portable olduğu iddia ediliyor. Şöyle yaparız.
Programlama Dillerindeki Çağrıları
QT
QThread.sleep() metod ise bildiğimiz sleep() türevlerini çağırmak yerine pthread_cond_timedwait() yöntemini tercih etmiş.
Aşağıdaki kodu buradan aldım.
boost
thread yazısına taşıdım.
C++11
std::this_thread yazısına taşıdım.
C#
Milisaniye alır. Şöyle kodlarız.
Java
Milisaniye alır. Şöyle kodlarız.
time(7) sayfasında yazdığına göre iki çeşit saat var. Bunlar Software clock ve Hardware clock.
Software clock jiffies cinsinden ölçüm yapıyor. Jiffy Linux'ta sistem açıldığından beri geçen software tickleri gösterir. Linux 2.6 çekirdeğinden itibaren bir jiffy ticki 0.004 saniyeye eşit. (4 mili saniye).
Bir çok sistem çağrısı (sleep, select gibi) software clock ile çalıştığı için her zaman tam istenilen çözünürlüğü sağlamayabilirler.
Hardware clock ise direkt donanım kesmesine bağlı olduğu için çok daha hassatır. Burada donanıma bağlı olan Time Stamp Counter değerini rdtsc komutu ile okuma örneği bulunuyor.
Sleep ve Gerçek Zamanlı Olmayan İşletim Sistemleri
Gerçek zamanlı olmayan işletim sistemlerinde herhangi bir sleep türevi uygulamayı tam istenilen zamanda uyandırmayı garanti etmez!. Aşağıdaki şekilde durum görülebilir.
High-resolution timers
Diğer timerlara göre çok daha yüksek çözünürlük imkanı sağlarlar. High resolution timer'lar jiffy ile kısıtlanmazlar.
High-Resolution Timers
Before Linux 2.6.21, the accuracy of timer and sleep system calls (see
below) was also limited by the size of the jiffy.
Since Linux 2.6.21, Linux supports high-resolution timers (HRTs),
optionally configurable via CONFIG_HIGH_RES_TIMERS. On a system that
supports HRTs, the accuracy of sleep and timer system calls is no
longer constrained by the jiffy, but instead can be as accurate as the
hardware allows (microsecond accuracy is typical of modern hardware).
You can determine whether high-resolution timers are supported by
checking the resolution returned by a call to clock_getres(2) or look‐
ing at the "resolution" entries in /proc/timer_list.
HRTs are not supported on all hardware architectures. (Support is pro‐
vided on x86, arm, and powerpc, among others.)
Windows
1. Sleep
#include <window.h> yapıldıktan sonra Sleep() metodu ile milisaniye kadar uyumak mümkün.
#include <Windows.h>
int main()
{
Sleep(100);
return 0;
}
Sleep ile getTickCount() beraber kullanılarak ölçüm yapınca verilen süreden biraz daha fazla uyunduğu görülebilir. 500 ms. yerine 515 ms. uyunması gibi.2. WaitableTimer
Sleep()'ten daha hassas bir zaman kullanabilmemizi sağlar. Zaman 100 nanosaniye çözünürlüğündedir.
#include <windows.h>
void usleep(__int64 usec) //microsecond
{
HANDLE timer;
LARGE_INTEGER ft;
ft.QuadPart = -(10*usec); //100 nanosecond interval, - value is relative time
timer = CreateWaitableTimer(NULL, TRUE, NULL);
SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
}
POSIX metodları
1. nanosleep() - Bir sinyal tarafından yarıda kesilebilir
Metodun imzası şöyle
#include <time.h>
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
nanosleep() nanosaniye cinsinden bir süre verilerek kullanılabiliyor. Posix ile gelen yüksek çözünürlüklü bir timer. nanosleep() ile beklemeye başlayan bir thread istenilen süre geçmeden de uyandırılabilir. İstenilen süre kadar uyumak için kullanılması gereken kod parçasını burada bulabilirsiniz. Sinyal tarafından yarıda kesilme ihtimaline karşı while döngüsü içinde kullanılıyor.#include <time.h>
...
struct timespec sleepTime;
struct timespec time_left_to_sleep;
sleepTime.tv_sec = 0;
sleepTime.tv_nsec = 1000;
while( (sleepTime.tv_sec + sleepTime.tv_nsec) > 0 )
{
nanosleep(&sleepTime, &time_left_to_sleep);
sleepTime.tv_sec = time_left_to_sleep.tv_sec;
sleepTime.tv_nsec = time_left_to_sleep.tv_nsec;
}
2. clock_nanosleep()
Metodun imzası şöyle
#include <time.h>
int clock_nanosleep(clockid_t clock,int flag,const timespec *rqtp,timespec *rmtp);
clock_nanosleep ile nanosleep gibi uyumak mümkün. Fark olarak clock_nanosleep() çeşitli clock tipleri kullanmamıza imkan tanır.Like nanosleep(2), clock_nanosleep() allows the caller to sleep for an interval specified with nanosecond precision. It differs in allowing the caller to select the clock against which the sleep interval is to be measured, and in allowing the sleep interval to be specified as either an absolute or a relative value. The clock_id argument [...] can have one of the following values: CLOCK_REALTIME A settable system-wide real-time clock. CLOCK_MONOTONIC A non-settable, monotonically increasing clock that measures time since some unspecified point in the past that does not change after system startup. CLOCK_PROCESS_CPUTIME_ID A settable per-process clock that measures CPU time consumed by all threads in the process.
Özellikle ntpd ile değişebilen duvar saatine yani CLOCK_REALTIME saatine göre uyumak için nanosleep() yerine bu metod kullanılmalıdır.
Örneğin 0.5 milisaniye uyumak için şöyle yaparız.
#include <time.h>
main()
{
struct timespec ts;
int i;
ts.tv_sec = 0;
ts.tv_nsec = 500000; /* 0.5 milliseconds */
for (i = 0; i < 1000; i++) {
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
}
}
İkinci parametre 0 olarak geçilirse, şu andan itibaren belirtilen süre kadar uyu anlamına geliyor. Eğer TIMER_ABSTIME (değeri 1 olarak tanımlıdır) kullanılırsa, belirtilen saat gelinceye kadar uyu anlamına geliyor. Yani sabit bir süre hesaplamak yerine, saat veriyoruz.Aşağıdaki kodda şimdiki zaman alınıp, sonra mutlak zaman hesaplandığı için yukarıdaki örnek ile aynı kapıya çıkar.
struct timespec Time;
clock_gettime(CLOCK_REALTIME, &(Time));
while(1){
Time.tv_nsec += 416000;
if(Time.tv_nsec > 999999999){
(Time.tv_sec)++;
Time.tv_nsec -= 1000000000;
}
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &(Time), NULL);
//Do something
}
usleep() mikrosaniye (saniyenin milyonda biri) cinsinden bir süre verilerek kullanılabiliyor. nanosleep()'ten farklı olarak yarıda kesilirse kalan süreyi alabilme seçeneği yok. Şöyle kodlarız.
#include <unistd.h>
int main()
{
usleep(100*1000); /* sleep for 100 milliSeconds */
return 0;
}
En son Posix standardı sürümünde nanosleep() bu metoda tercih edilmeli denilse de nanosleep'in olmadığı durumlarda kullanılabilir. Burada dikkat edilmesi gereken nokta usleep metodunda şöyle bir cümle geçiyor.Yani usleep metodu ile 1 saniyeden fazla uyuma yapmak mümkün olmayabilir.The useconds argument shall be less than one million
4. sleep() - Bir sinyal tarafından yarıda kesilebilir
sleep() saniye cinsinden bir süre verilerek kullanılabiliyor. Eğer 0'dan farklı bir değer dönerse, metod yarıda kesilmiştir ve kalan süreyi belirtir.
sleep (0) yield ile aynı anlama gelir. Yani thread çalışmak için süresi varsa bile, süresinden feragat eder.
5. select
select ile mikrosaniye cinsinden uyuma yapmak ta mümkün. Hatta portable olduğu iddia ediliyor. Şöyle yaparız.
int usleep(long usec)
{
struct timeval tv;
tv.tv_sec = usec/1000000L;
tv.tv_usec = usec%1000000L;
return select(0, 0, 0, 0, &tv);
}
Şöyle yaparızselect(NULL, NULL, NULL, NULL, 1.0);
Burada EINTR biz sistem çağrısı yaparken, bir sinyal gelip gelmediğini kontrol etmemize yarıyor. Aslında yeni POSIX standardında EINTR gelse bile sistem çağrısı kısmen başarılı olmuş olabilir. Bu yüzden sistem çağrısının sonucuna -1 kontrolü yapmak yerine errno değikenini ayrıca kontrol etmek lazım sanırım.Programlama Dillerindeki Çağrıları
QT
QThread.sleep() metod ise bildiğimiz sleep() türevlerini çağırmak yerine pthread_cond_timedwait() yöntemini tercih etmiş.
Aşağıdaki kodu buradan aldım.
boost
thread yazısına taşıdım.
C++11
std::this_thread yazısına taşıdım.
C#
Milisaniye alır. Şöyle kodlarız.
Thread.Sleep(1000);
Thread.Sleep(0) ile program yield eder.Java
Milisaniye alır. Şöyle kodlarız.
Thread.sleep(interval);
Hiç yorum yok:
Yorum Gönder