2013-02-07 65 views
7

Tôi đang cố gắng thực thi một vài lệnh hoặc hàm N lần trong một giây. Làm thế nào tôi có thể làm điều này trong java? Như sau ...cách thực hiện vòng lặp n lần trong 1 giây

//in one second 
while(N) 
{ 
    printf("........."); 
    int x=0; 
    printf("The value of x is "); 
} 

nhưng câu hỏi thực sự đi sâu hơn chút .. Tôi cố gắng để vẽ pixel bằng tay và tôi muốn không của vòng một hiệu ứng thứ hai ... do đó về cơ bản, nó có để thực hiện N lần trong một giây (nhưng điều này được thực hiện vô cùng)

cảm ơn trước

+0

Nếu đây chỉ là bài tập về nhà, bạn có thể sử dụng một vòng lặp bận rộn kiểm tra thời gian hiện tại trong mỗi lần lặp –

+0

Bạn không thể chắc chắn chính xác có bao nhiêu lần một chu kỳ kéo dài trong vòng lặp của bạn trong một phút nếu bạn đang nói về thường xuyên của hệ điều hành. Để chắc chắn bạn cần một RTOS hoặc đoán nó bằng cách đo thời gian giữa mỗi chu kỳ. –

+1

Bạn có muốn nó chạy mọi số lượng N trong 1 giây hoặc nhiều nhất là N trong 1 giây? – Adrian

Trả lời

5

Bạn không bao giờ có thể chắc chắn nó sẽ xảy ra chính xác N lần mỗi giây, nhưng nó đi như thế này:

long taskTime = 0; 
long sleepTime = 1000/N; 
while (true) { 
    taskTime = System.currentTimeMillis(); 
    //do something 
    taskTime = System.currentTimeMillis()-taskTime; 
    if (sleepTime-taskTime > 0) { 
    Thread.sleep(sleepTime-taskTime); 
    } 
} 
+0

Vấn đề là, những lệnh không thể thực hiện trong một đánh dấu ... Vì vậy, chúng ta có thể làm cho nó ngủ cho 1000/N –

+0

Đó không phải là một vấn đề - đo thời gian nhiệm vụ và trừ nó từ thời gian ngủ. Tôi sẽ chỉnh sửa câu trả lời ... – Dariusz

+0

Nit: Điều này sẽ chỉ làm việc khoảng cho N nhỏ hơn (nói 30 hoặc ít hơn). Đối với N lớn hơn, nhiều N sẽ cần phải được thực hiện * mỗi lần * trước khi ngủ. –

0

Thay đổi vòng lặp thành while(true).

Kiểm tra thời gian bằng mili giây trước vòng lặp while của bạn. Ở cuối vòng lặp while, nhận được thời gian tính bằng mili giây và xem liệu 1000 trong số đó đã qua chưa. Nếu vậy break.

+0

Điều này giúp ... nhưng câu hỏi thực sự đi sâu hơn một chút .. Tôi đang cố gắng vẽ điểm ảnh theo cách thủ công và tôi muốn không có phép quay trên mỗi giây ... , nó phải thực hiện N lần trong một giây (Nhưng điều này được thực hiện vô hạn) –

+0

Vì vậy, điều này sẽ ... thực hiện trong một giây bất kể bao nhiêu lần lặp được lặp lại. Đó không phải là vấn đề, phải không? – Dariusz

+0

Tôi hiểu nhầm câu hỏi. Từ những gì tôi hiểu là bạn muốn vòng lặp thực thi chính xác N lần trong một giây cụ thể. –

0

Pseudo Code:

Create Timer t; 
t.Start; 
int counter = N; 
While ((t.Elapsedtime < 1 Second) AND (N > 0)) 
{ 
    call your_function(); 
    N--; 
} 

your_function() 
{ 
    printf("........."); 
    int x=0; 
    printf("The value of x is "); 
} 
0
long start = System.currentTimeMillis(); 
while (System.currentTimeMillis() - start <= 1000) { 
    // Your code goes here 
} 

Tất cả nó sẽ chăm sóc là mã của bạn sẽ được looped qua cho 1000 mili giây. Số lần nó được thực hiện là không chắc chắn và có thể thay đổi theo từng lần chạy.

3

Tôi sẽ lật vấn đề: không giới hạn vòng lặp thành N lần trong một giây. Thay vào đó, xử lý N đơn vị công việc phân bố đồng đều trong thời gian mong muốn.

Đó là, tính toán bao nhiêu thời gian đã trôi qua kể từ bắt đầu (hoặc công việc trước đây), suy đó vào tỷ lệ công việc, và làm điều đó nhiều việc (yếu tố đầu/trước thời gian và số lượng công việc đã được thực hiện). Đây là nền tảng cơ bản của nhiều công cụ trò chơi/hoạt hình - một số "delta time".

Sau đó gọi yield ở cuối mỗi vòng lặp để "đẹp" - hay đúng hơn, để tránh ăn 99% + mức sử dụng CPU! Bản thân năng suất có độ phân giải tối thiểu , nhưng hiệu ứng nói chung là thích hợp, đặc biệt là khi nội suy phù hợp.

Vì cách tiếp cận nội suy được sử dụng, nên làm việc cho tất cả N (có thể chạy trong thời gian quy định), ngay cả khi nó có nghĩa là thực hiện nhiều vòng lặp N. Nó cũng có thể là không có công việc nào có thể được thực hiện bất kỳ vòng lặp cụ thể cho một N nhỏ nhưng yield làm cho loại "thêm bận rộn looping" giá rẻ về sử dụng CPU .


Dưới đây là một số mã giả để in ra 20 "x" s trong một giây, nơi now lợi nhuận giây phân đoạn:

rate = 20  // per second - "N times per second" 
done = 0 
goal = 1 * rate // same as rate for 1 second 
start = now() 
while done < goal: 
    target = floor((now() - start) * rate) 
    work = (target - done) // work might be 0, that's okay 
    for 0 upto work: 
     print("x") 
    done += work 
    yield() 

Trong trường hợp này nó rất dễ dàng để suy ra từ khi bắt đầu thời gian vì công thức tỷ lệ không đổi.Sử dụng "thời gian delta" dựa trên thời gian kể từ khi công việc cuối cùng (hoặc vòng lặp) là tương tự và phù hợp khi không có công thức riêng biệt, nhưng hơi phức tạp hơn và có thể dẫn đến lỗi trôi dạt tinh tế.


Độ phân giải thời gian của một thực tếsleep/yield là thực hiện phụ thuộc và thay đổi theo bởi hệ thống. Ví dụ: nó có thể nằm trong khoảng từ 1ms on Linux to 10-15ms on windows.

Trong Ngoài đối phó với một vùng đồng bằng thời gian, giai đoạn sleep có thể được thay đổi, như mỗi câu trả lời Dariusz Wawer của. Tuy nhiên, điều này làm tăng thêm độ phức tạp và đơn giản là yield thường đủ.

1

Rất khó để có thể chính xác với các giải pháp được đề xuất. Thay vì tính toán khoảng cách giữa các lần lặp, hãy tính toán thời gian tuyệt đối khi lặp lại tiếp theo sẽ được thực thi. Điều này là chính xác hơn bởi vì các lần lặp lại không phụ thuộc vào những lần lặp lại trước đó.

long startTime = System.currentTimeMillis(); 
long msPerIteration = 1000000/iterationsPerSecond; 
long i=0; 
while (true) { 
    // do stuff 

    long msWaiting = startTime + (msPerIteration * ++i) - System.currentTimeMillis(); 

    if (msWaiting > 0) 
     Thread.sleep(msWaiting); 
} 
Các vấn đề liên quan