2014-05-09 15 views
6

Tôi cần thực thi một số mã 1000 lần mỗi giây. Tôi muốn làm điều gì đó như:Làm thế nào để thực hiện một vòng lặp thời gian?

set up interval timer 
while (1) 
{ 
    wait for timer 
    do something 
} 

nỗ lực của tôi trông giống như

// Create timer 
timer_t timerid; 
struct sigevent sev; 

sev.sigev_notify = SIGEV_SIGNAL; 
sev.sigev_signo = SIGUSR1; 

if (timer_create(CLOCK_REALTIME, &sev, &timerid)) 
{ 
perror("timer_create"); 
exit(1); 
} 

// Every one mSec (10^6 nsec) 
struct itimerspec its; 
its.it_value.tv_sec = 0; 
its.it_value.tv_nsec = 1000000; 
its.it_interval.tv_sec = 0; 
its.it_interval.tv_nsec = 1000000; 
if (timer_settime(timerid, 0, &its, NULL)) 
{ 
perror("timer_settime"); 
exit(1); 
} 

// Create mask to wait for SIGUSR1 
sigset_t set; 
sigemptyset(&set); 
sigaddset(&set, SIGUSR1); 

while (1) 
{ 
int sig; 

// Wait for the timer: Do this loop once per millisecond 
sigwait(&set, &sig); 

    (do something) 
} 

Khi tôi cố gắng này, tôi chỉ nhận được "tài khoản tín hiệu 1 định nghĩa" ở giao diện điều khiển và thoát chương trình của tôi. Điều này không đáng ngạc nhiên vì đây là hành động mặc định cho tín hiệu. Nếu tôi đặt tín hiệu để SIG_IGN sử dụng sigaction (2), tôi không bao giờ nhận được để tôi (làm điều gì đó).

Tôi giả sử tôi cần phải làm điều gì đó với tính chất (2), nhưng tôi không thấy tùy chọn cho "phân phối tín hiệu". Tôi không muốn bỏ qua tín hiệu hoặc thực hiện hành động mặc định hoặc gọi hàm. Cách tốt nhất để hoàn thành mục tiêu của tôi là gì?

Hoặc tôi chỉ có thể từ bỏ và đưa tôi (làm điều gì đó) trong một hàm :-)

Edit: Tôi thực hiện ý tưởng timerfd, và có vẻ như được làm việc. Về lỗi tiếp theo ...

+0

Tại sao không chỉ đơn giản là 'nanosleep' trong khoảng thời gian thích hợp? Lưu ý rằng bạn cần tự tính toán khoảng thời gian dựa trên dấu thời gian tiếp theo khi hành động cần thực thi và thời gian hiện tại. (Nếu bạn luôn đợi 1ms giữa các lần lặp, bạn sẽ thực hiện ít hơn 1000 lần lặp mỗi giây, chính xác có bao nhiêu tùy thuộc vào thời gian cần để "làm điều gì đó".) – user4815162342

+0

Có một tập hợp khá lớn các hành động có thể xảy ra bên cạnh SIG_IGN. –

+0

@ n.m "Có một tập hợp khá lớn các hành động có thể xảy ra bên cạnh SIG_IGN." Trích dẫn từ http://man7.org/linux/man-pages/man2/sigaction.2.html: sa_handler chỉ định hành động được liên kết với signum và có thể là SIG_DFL cho hành động mặc định, SIG_IGN bỏ qua tín hiệu này hoặc con trỏ đến chức năng xử lý tín hiệu. Các tùy chọn khác có sẵn là gì? – rich

Trả lời

4

Vì bạn đã gắn thẻ câu hỏi của mình với embedded-linux Tôi cho rằng tính di động không phải là vấn đề. Trong trường hợp đó, bạn có thể muốn xem timerfd. Nó sẽ cho phép bạn sử dụng select(2)/poll(2) để nhận sự kiện hẹn giờ của mình. Nó cũng sẽ làm cho nó dễ dàng hơn để kết hợp bộ đếm thời gian với các nguồn sự kiện khác như các bộ mô tả tập tin.

+0

+1 để sử dụng timerfd. Bằng cách đó, chương trình của bạn sẽ vẫn hoạt động ngay cả khi bạn liên kết đến thư viện sử dụng SIGUSR1 cho thư viện nội bộ. –

0

Tôi nghĩ bạn nên đặt trình xử lý tín hiệu thực như được đề xuất bởi n.m. Hãy xem man sigaction cho phiên bản Linux của bạn. Bạn có thể gọi do_something trong trình xử lý tín hiệu (và chờ một thứ khác để chấm dứt chương trình) hoặc chỉ có một trình xử lý trả về và giữ cho bạn logic sigwait.

Các vấn đề liên quan