সময়ের সাথে দীর্ঘমেয়াদী সময় ব্যয় না করে খুব স্বল্প বিরতিতে অবিকল ইউনিক্স কমান্ডটি চালান


38

প্রশ্ন

আমি দীর্ঘ সময়কালে প্রতি সেকেন্ডে অবিকল UNIX কমান্ড চালাতে সক্ষম হতে চাই ।

আমার একটি সমাধান দরকার, যা একটি নির্দিষ্ট সময়ের পরে পিছিয়ে থাকে না, কারণ সময়টি কমান্ড নিজেই কার্যকর করার জন্য প্রয়োজন। ঘুম , দেখুন এবং একটি নির্দিষ্ট অজগর স্ক্রিপ্ট সবই আমাকে এই ব্যর্থ করেছিল।

মাইক্রোকন্ট্রোলারের যেমন http://Ardino.cc এ আমি হার্ডওয়্যার ক্লক বিঘ্নের মাধ্যমে এটি করতাম। অনুরূপ সময়-সঠিক শেল স্ক্রিপ্ট সমাধান আছে কিনা তা আমি জানতে চাই। স্ট্যাকএক্সচেঞ্জ.কমের মধ্যে আমি যে সমস্ত সমাধান পেয়েছি, তার ফলে কয়েক ঘন্টার বেশি সময় চলতে থাকলে একটি লক্ষণীয় সময় পিছিয়ে পড়ে। বিস্তারিত নীচে দেখুন.

ব্যবহারিক উদ্দেশ্য / প্রয়োগ

আমি পরীক্ষা করতে চাই যে আমার নেটওয়ার্ক সংযোগটি ncপ্রতি 1 সেকেন্ডে (নেটক্যাট) মাধ্যমে টাইমস্ট্যাম্পগুলি প্রেরণ করে অবিচ্ছিন্নভাবে চলছে কিনা ।

প্রেরকের:

precise-timestamp-generator | tee netcat-sender.txt | nc $receiver $port

রিসিভার:

nc -l -p $port > netcat-receiver.txt

সমাপ্তির পরে, দুটি লগের তুলনা করুন:

diff netcat-sender.txt netcat-receiver.txt

ভিন্নতা হ'ল অপরিবর্তিত টাইমস্ট্যাম্পগুলি। এ থেকে আমি জানতে পারি যে আমার ল্যান / ডাব্লু / ডাব্লু / ইএসপি সমস্যাগুলি কখন তৈরি করে।


সমাধান স্লিপ

while [ true ]; do date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done | tee timelog-sleep.txt

সময়ের সাথে সাথে একটি নির্দিষ্ট অফসেট পাওয়া যায়, কারণ লুপের মধ্যে থাকা কমান্ডটিও কিছুটা সময় নেয়।

স্পষ্টতা

cat timelog-sleep.txt

2012-07-16 00:45:16
[...]
2012-07-16 10:20:36

সেকেন্ডগুলি বিস্তৃত: 34520

wc -l timelog-sleep.txt

ফাইলে লাইনগুলি: 34243

যথার্থ সংক্ষিপ্তসার:

  • 34520-34243 = 277 সময়সীমার সমস্যা
  • 34520/34243 = 1.008 = 0.8% বন্ধ

সমাধান পুনরাবৃত্তি পাইথন

পাওয়া গেছে: ইউনিক্স কমান্ড প্রতি x সেকেন্ড চিরতরে পুনরাবৃত্তি করুন

repeat.py 1 "date '+%Y-%m-%d %H:%M:%S'" >> timelog-repeat-py.txt

অফসেট সময় এড়াতে বলে মনে করা হয়েছে, তবে তা করতে ব্যর্থ।

স্পষ্টতা

wc -l timelog-repeat-py.txt

2012-07-16 13:42:44
[...]
2012-07-16 16:45:24

সেকেন্ড বিস্তৃত: 10960

wc -l timelog-repeat-py.txt

ফাইলে লাইনগুলি: 10859

যথার্থ সংক্ষিপ্তসার:

  • 10960-10859 = 101 সময়সীমার সমস্যা
  • 10960/10859 = 1.009 = 0.9% ছাড়

সমাধান দেখুন

watch -n 1 "date '+%Y-%m-%d %H:%M:%S' >> ~/Desktop/timelog-watch.txt"

স্পষ্টতা

wc -l timelog-watch.txt
2012-07-16 11:04:08
[...]
2012-07-16 13:25:47

সেকেন্ড বিস্তৃত: 8499

wc -l timelog-watch.txt

ফাইলে লাইনগুলি: 8366

যথার্থ সংক্ষিপ্তসার:

  • 8499-8366 = 133 সময় সমস্যা।
  • 8499/8366 = 1.016 = 1.6% বন্ধ।

5
প্রয়োজনীয় রেজোলিউশন, যথার্থতা কী এবং আপনার এটির প্রয়োজন কেন / আপনি কীসের জন্য এটি ব্যবহার করছেন?
জিপ্পি

আপনি niceঘুমন্ত প্রক্রিয়া যদি কি ঘটে ?
টিলো উইক্লুন্ড

1
আশা করি আপনি ঘুম () কলে দেরি কমাতে বাস্তব সময় নির্ধারিত সময়সূচীটি ব্যবহার করছেন।
এমডিপিসি

এটি আমাকে আঘাত করে যে আপনার সময়টি সর্বদা বাক্সের বর্তমান অপারেটিং অবস্থার দ্বারা প্রভাবিত হতে চলেছে। যদি আপনি যে প্রোগ্রামটিকে যত্নবান হন তার কিছু ক্যাশে থেকে লোড হওয়ার কারণ হয়ে থাকে তবে আপনি সময় বাড়তে পারবেন, যদি না আপনি গ্যারান্টি দিতে না পারেন যে প্রোগ্রামটির সাধারণ রানটাইম আপনি চান অন্তরটির চেয়ে উল্লেখযোগ্যভাবে কম। আমি একটি রিয়েলটাইম সিস্টেমে থাকতে চাই, অন্য কেউ লগইন না করে, বা একক ব্যবহারকারী মোডে উল্লেখযোগ্যভাবে বাদ দেওয়া সেটআপে। সম্ভবত আরও ভাল সমাধান হ'ল লুপটি নিজেই করার জন্য প্রশ্নে প্রোগ্রামটি পরিবর্তন করে অন্য প্রোগ্রাম থেকে প্রার্থনা করার পরিবর্তে।
হ্যাক 21

2
প্রতিটি কমান্ডকে তার নিজস্ব থ্রেডে লঞ্চ করুন, এইভাবে কোনও আইও-সম্পর্কিত ব্লকিং আপনার সময়কে দূরে রাখবে না।
জোয়েল করনেট

উত্তর:


12

এই পার্ল স্ক্রিপ্টটি কীভাবে আমি সবেমাত্র কাজটি করতে পারি?

#!/usr/bin/perl

use strict;
use warnings;
use Time::HiRes qw/time sleep/;

sub launch {
    return if fork;
    exec @_;
    die "Couldn't exec";
}

$SIG{CHLD} = 'IGNORE';

my $interval = shift;
my $start = time();
while (1) {
    launch(@ARGV);
    $start += $interval;
    sleep $start - time();
}

ব্যবহার করুন: perl timer.pl 1 date '+%Y-%m-%d %H:%M:%S'

এটি একটি ছাড়াই ছাড়াই 45 মিনিট ধরে চলেছে, এবং আমার সন্দেহ হয় যে যদি না ক) সিস্টেমের লোড এত বেশি না হয়ে যায় যে কাঁটাচামচ () একটি সেকেন্ডের বেশি নেয় বা খ) একটি লিপ সেকেন্ড isোকানো হয় না।

এটি গ্যারান্টি দিতে পারে না যে কমান্ডটি ঠিক দ্বিতীয় ব্যবধানে চলে, কারণ কিছু ওভারহেড রয়েছে, তবে আমি সন্দেহ করি যে এটি একটি বাধা-ভিত্তিক সমাধানের চেয়ে আরও খারাপ is

আমি এটি প্রায় এক ঘন্টা ধরে date +%Nচালিয়েছি (ন্যানোসেকেন্ডস, জিএনইউ এক্সটেনশন) এবং এটিতে কিছু পরিসংখ্যান চালিয়েছি। এর মধ্যে সবচেয়ে পিছনে ছিল 155 ডলার মাইক্রোসেকেন্ড। গড় (গাণিতিক গড়) 216, সে, মিডিয়ান 219, সে, স্ট্যান্ডার্ড বিচ্যুতি 42। সে। এটি সময়ের চেয়ে 270 95s 95% এর চেয়ে বেশি দ্রুত চলেছিল। আমি মনে করি না আপনি এটি কোনও সি প্রোগ্রাম বাদ দিয়ে পরাজিত করতে পারবেন।


1
আমি এটি 1 সেকেন্ডের ব্যবধান সহ অন্য কোনও সক্রিয় ব্যবহারকারীর অ্যাপ্লিকেশন না দিয়ে রাতারাতি চালিয়েছি, এবং এটি 29241 সেকেন্ডে চলেছে, একটিও ছাড়ানো দ্বিতীয় ছাড়াই! এটি আমার উদ্দেশ্য মাপসই করা হবে। তারপর আমি আবার এই সকালে 0.1 সেকেন্ড একজন ব্যবধান সঙ্গে, দৌড়ে GNU dateসঙ্গে +%N: এবং মাত্র 3 মিনিট পরে এটি যে ত্রুটি ছুড়ে ফেলে Time::HiRes::sleep(-0.00615549): negative time not invented yet at ~/bin/repeat.pl line 23.আমার সংরক্ষিত লিপিতে লাইন 23:sleep $start - time();
porg

আপনি যদি এটি 0.01 সেকেন্ড বা 0.001 সেকেন্ড অন্তর দিয়ে চালান তবে প্রোগ্রামটি "নেতিবাচক সময়" ত্রুটিটি বন্ধ না হওয়া পর্যন্ত এটি কয়েক সেকেন্ড বা তার কম সময়ের কথা। কিন্তু আমার উদ্দেশ্য এটি ফিট!
পোজ

28

পসিক্স ualarm()ফাংশন আপনাকে মাইক্রোসেকেন্ড যথার্থতার সাথে আপনার প্রক্রিয়াটি পর্যায়ক্রমে সিগন্যাল করতে কার্নেলকে সময় নির্ধারণ করতে দেয়।

একটি সহজ প্রোগ্রাম হুইপ আপ:

 #include<unistd.h>
 #include<signal.h>
 void tick(int sig){
     write(1, "\n", 1);
 }
 int main(){
     signal(SIGALRM, tick);
     ualarm(1000000, 1000000); //alarm in a second, and every second after that.
     for(;;)
         pause();
 }

কম্পাইল

 gcc -O2 tick.c -o tick

তারপরে আপনার সময় মতো যা করা দরকার তা এটির সাথে সংযুক্ত করুন:

./tick | while read x; do
    date "+%Y-%m-%d %H:%M:%S"
done | tee timelog-sleep.txt

এর জন্য আমার কি বিশেষ শেল বা সি-স্টাডি দরকার? আমি এটি সংকলন করেছি (যা অনুপস্থিত প্রত্যাবর্তনের ক্ষেত্রে একটি ছোট সতর্কতা দিয়েছে) তবে কোনও আউটপুট উত্পাদিত হয়নি।
গণিত

@ ম্যাথ সহ -std=c99, আপনি নিখোঁজ রিটার্ন সম্পর্কে সতর্কতা পাবেন না। অন্যথায়, আপনার বিশেষ কিছু লাগবে না। আপনি অতিরিক্ত শূন্যটি ভুল লিখেছেন? strace ./tickএটি একটি সিস্কেল দৃষ্টিকোণ থেকে কী করছে তা আপনাকে দেখাবে
ডেভ

আমি পেয়েছি: gcc -O2 -std = c99 -o tick.c। Tick.c: ফাংশনটিতে 'main': tick.c: 10: 5: সতর্কতা: ফাংশন 'ওয়ালারম' এর অন্তর্নিহিত ঘোষণা [-Wompभाग- ফাংশন-ঘোষণা ] tick.c: ফাংশনে 'টিক': tick.c: 5: 10: সতর্কতা: 'লেখার' ফেরতের মান উপেক্ষা করে, অ্যাট্রিবিউট_অনুজেড_সাল্ট [-আযুক্ত-ফলাফল]] সহ ঘোষিত :: মনে হচ্ছে যে আমার সিস্টেম (উবুন্টু 12.04) করে এটি সমর্থন না। তবে কমপক্ষে একটি ম্যান পৃষ্ঠা রয়েছে যা ইউআরআরএম unistd.h এ থাকা উচিত। (gcc is 4.6.3)
গণিত

28

আপনি কি watchপ্যারামিটার দিয়ে চেষ্টা করেছেন --precise?

watch -n 1 --precise "date '+%Y-%m-%d %H:%M:%S.%N' >> ~/Desktop/timelog-watch.txt"

ম্যান পৃষ্ঠা থেকে:

সাধারণত, এই ব্যবধানটি একটি রান কমান্ডের সমাপ্তি এবং পরবর্তী রান শুরুর মধ্যবর্তী সময়ের সর্বাধিক অর্থ হিসাবে ব্যাখ্যা করা হয়। তবে, -p বা - পূর্ববর্তী বিকল্পের সাহায্যে আপনি প্রতি বিরতিতে সেকেন্ডে কমান্ড চালানোর জন্য নজরদারি করতে পারেন। এনটিপিটাইম দিয়ে এটি ব্যবহার করে দেখুন এবং কীভাবে ক্রমাগত বৃদ্ধি হয় সেখানে সাধারণ মোডের বিপরীতে ভগ্নাংশের সেকেন্ডগুলি (প্রায়) একই থাকে কীভাবে তা লক্ষ্য করুন।

যদিও প্যারামিটারটি আপনার সিস্টেমে উপলভ্য নয়।

আপনার প্রোগ্রামটির সম্পাদনা যখন এক সেকেন্ডের বেশি প্রয়োজন হয় তখন কী ঘটতে হবে তাও আপনার বিবেচনা করা উচিত। পরবর্তী নির্ধারিত সম্পাদনটি বাদ দেওয়া উচিত, না এটি দেরিতে চালানো উচিত?

আপডেট : আমি কিছু সময়ের জন্য স্ক্রিপ্টটি চালিয়েছি এবং এটি একটি পদক্ষেপও ছাড়েনি:

2561 lines
start: 2012-07-17 09:46:34.938805108
end:   2012-07-17 10:29:14.938547796

আপডেট করুন:--precise পতাকা একটি ডেবিয়ান উপরন্তু হয়, প্যাচ তবে বরং সহজ: http://patch-tracker.debian.org/patch/series/view/procps/1:3.2.8-9squeeze1/watch_precision_time.patch


ঠিক যেতে হবে। আমি যদি এটি +10 করতে পারি
krlMLr

কোন সংস্করণ watchএই বিকল্পটি সমর্থন করে? এটি আমি যে মেশিনগুলি পরীক্ষা করেছিলাম তার কোনওটিতেই এটি ছিল না।
টাইলার

এর সংস্করণ 0.3.0, যা উবুন্টু 12.04 এর বর্তমান সংস্করণ। এটি প্রোপস প্যাকেজের 3.2.8-11ubuntu6 সংস্করণ থেকে আসে।
ড্যানিয়েল কুলম্যান

হুঁ, প্রোপস উত্স প্যাকেজ সমর্থন করে না --precise। এটি একটি ডেবিয়ান সংযোজন (3.2.8-9, ওয়াচ_প্রিসিশন_টাইম.প্যাচ)
ড্যানিয়েল কুলম্যান

1
ঠিক আছে, তবে প্রশ্নের মন্তব্যে এমডিপিসির মতোই বলেছে: আপনার সিস্টেমে খুব বেশি বোঝা থাকা অবস্থায় এটি ব্যর্থও হতে পারে। আমি কেবল এটি স্ট্রেসের সাথে সংযুক্ত করে পরীক্ষা করেছি (ডিস্ক এবং কোরগুলিতে বোঝা চাপানো) এবং এটি পেয়েছি: 2012-07-24 07:20:21.864818595 2012-07-24 07:20:22.467458430 2012-07-24 07:20:23.068575669 2012-07-24 07:20:23.968415439 রিয়েল টাইম স্টাফ (কর্নেল ইত্যাদি) কোনও কারণেই বাইরে রয়েছে!
গণিত

18

crontab1 মিনিটের রেজোলিউশন রয়েছে has যদি আপনি প্রতি মিনিটে পিছনে সময় সঞ্চিত হয়ে এবং তার পরের মিনিটে পুনরায় সেট করার সাথে ভাল থাকেন তবে এই প্রাথমিক ধারণাটি কাজ করতে পারে:

* * * * * for second in $(seq 0 59); do /path/to/script.sh & sleep 1s;done

নোট যে script.shপটভূমিতে চালিত হয়। লুপের প্রতিটি পুনরাবৃত্তির সাথে জমা হওয়া ল্যাগটি হ্রাস করতে সহায়তা করা উচিত।

কত ল্যাগ sleepউত্পন্ন করে তার উপর নির্ভর করে , পরের মিনিটের দ্বিতীয় 0 দিয়ে দ্বিতীয় 59 ওভারল্যাপ করার সম্ভাবনা রয়েছে।

কিছু ফলাফল টস করতে সম্পাদনা করুন , প্রশ্নের মতো একই ফরম্যাটে:

$ cat timelog-cron
2012-07-16 20:51:01
...
2012-07-16 22:43:00

1 ঘন্টা 52 মিনিট = 6720 সেকেন্ড

$ wc -l timelog-cron
6720 timelog-cron

0 টিমিং সমস্যা, 0% বন্ধ। যেকোন সময় জমে প্রতি মিনিটে পুনরায় সেট করা হয়।


1
আমি জিজ্ঞাসা করতে পারি কেন এটিকে নিম্নমানের করা হয়েছিল?
ইজকাটা

2
এটি একটি
কুরুচিপূর্ণ

2
@ হাহামু এটি সম্পর্কে কুরুচিপূর্ণ কি? পিসির সাধারণ উদ্দেশ্যে ওএসগুলি খুব সুনির্দিষ্ট সময়-সমালোচনামূলক ক্রিয়াকলাপগুলির জন্য নকশাকৃত নয়, তবে আপনি আরও কী আশা করতে পারেন? আপনি যদি "মার্জিত" এবং একেবারে সুনির্দিষ্ট সময় বলতে চান তবে আপনাকে আলাদা সিপিইউ শিডিয়ুলার ব্যবহার করতে হবে, বা একটি রিয়েল টাইম কার্নেলে স্যুইচ করতে হবে, বা ডেডিকেটেড হার্ডওয়্যার ইত্যাদি ব্যবহার করতে হবে এটি পুরোপুরি বৈধ সমাধান এবং আমি এর কোনও কারণ দেখতে পাই না downvotes। ক্রোনটির মাধ্যমে পর্যায়ক্রমে পুনরায় সমন্বয় না করে কেবল "ব্যাকগ্রাউন্ডে রান" রয়েছে এটির মধ্যে এটি অবশ্যই একটি উন্নতি।
jw013

1
প্লাস এটি থামানো সহজ। এটি একটি চক্রের মাঝখানে হত্যার ঝুঁকি নেওয়ার দরকার নেই - ক্রোনট্যাব থেকে এন্ট্রি সরিয়ে ফেলুন এবং মিনিট শেষে এটি নিজেরাই শেষ হয়।
ইজকাটা

আপনি শুধু ভাগ্যবান যে আপনার সিস্টেমে করছি cronদ্বিতীয় সুনির্দিষ্ট হয়, কিন্তু এটা ঘটনা না সাধারণভাবে।
দিমিত্রি গ্রিগরিয়েভ

15

আপনার সমস্যাটি হ'ল আপনি শেষ সময় ঘুমানোর পর থেকে যে সময়টি কেটে গেছে তার কথা বিবেচনা না করে আপনি আপনার প্রোগ্রামটি চালানোর পরে একটি নির্দিষ্ট সময়ের জন্য ঘুমাচ্ছেন ।

আপনি এটি বাশ বা অন্য কোনও প্রোগ্রামিং ল্যাঙ্গুয়েজ করতে পারেন, তবে পরবর্তী ঘুমের সময় নির্ধারণ করতে কতক্ষণ সময় নির্ধারণ করতে চাবিকাঠিটি ব্যবহার করা উচিত। আপনি ঘুমানোর আগে, ঘড়িটি পরীক্ষা করুন, আপনি কতটা সময় রেখেছেন তা দেখুন এবং তারতম্যটি ঘুমান।

প্রক্রিয়া শিডিয়ুলিং আপোস করার কারণে, আপনি ঠিক ঘড়ির টিকের উপরে উঠার নিশ্চয়তা দিচ্ছেন না, তবে আপনার মোটামুটি কাছাকাছি হওয়া উচিত (আনলড হওয়া কয়েক এমএসের মধ্যে বা কয়েকশো এমএসের মধ্যে)। এবং আপনি সময়ের সাথে সাথে ত্রুটি জমা করবেন না কারণ প্রতিবার আপনি প্রতিটি ঘুমের চক্রটিতে পুনরায় সংশ্লেষ করছেন এবং কোনও জমা হওয়া ত্রুটি মুছে ফেলছেন।

যদি আপনাকে ঘড়ির টিকটি ঠিক হিট করতে হয় তবে আপনি যা খুঁজছেন তা হ'ল একটি রিয়েল টাইম অপারেটিং সিস্টেম , যা ঠিক এই উদ্দেশ্যে তৈরি করা হয়েছে।


আমি মনে করি এটি খুব সম্ভাবনাও রয়েছে যে প্রোগ্রামগুলি পোরগ লক্ষ্যযুক্ত প্রক্রিয়াটি চালনার সময় ব্লকটি পরীক্ষা করেছে - যা তারা চালাচ্ছে তার মেশিনটি এড়াতে যৌক্তিকভাবে তাদের করা উচিত।
সাইমকিবিয়ান

আপনি অবরুদ্ধ করুন বা না করুন, প্রক্রিয়াটি ঠিক কাজ করে। যদি আপনি অবরুদ্ধ করেন তবে আপনি অবরুদ্ধ হওয়ার পরে বাকী সময়টি ঘুমান। আপনি যদি অবরুদ্ধ না হন, তবে অন্য সময় কাজ করার সময় আপনার টাইমিং থ্রেড বা প্রক্রিয়াটি ঘুমন্ত। যেভাবেই হোক, একই ফলাফল।
টাইলার

@ ইয়েলারল: কংক্রিট কমান্ড লাইনটি আপনার সমাধানের জন্য কেমন হবে?
পোরগ

আমি অনুমান করি আপনি @lynxlynxlynx এর
23'12

@ পোরগ আপনাকে date +%S.%Nসাব-সেকেন্ড যথার্থতার সাথে সেকেন্ডের সংখ্যা পেতে এবং উপ-দ্বিতীয় নির্ভুলতার usleepসাথে ঘুমাতে প্রয়োজন, তবে তার পরে এটি গণিতের বিষয় মাত্র।
টাইলার 5

7

আমি সর্বদা বিরতিতে ঠিক কিছু চালানো ছেড়ে দিয়েছি । আমি মনে করি আপনাকে একটি সি প্রোগ্রাম লিখতে হবে এবং আপনার নিজের কোড সহ 1-সেকেন্ডের ব্যবধানের অংশটি অতিক্রম না করার জন্য খুব যত্ন সহকারে মনোযোগ দিন। এটিকে কাজ করতে আপনাকে সম্ভবত থ্রেডিং বা একাধিক, আন্তঃসংযোগ প্রক্রিয়া ব্যবহার করতে হবে। থ্রেড-শুরুর সময় বা প্রক্রিয়া শুরু হওয়ার সময় ওভারহেড এড়াতে যত্ন নিন।

1993-এর প্রাসঙ্গিক তারিখগুলি মনে হয় এমন একটি রেফারেন্স: সিপিইউ ব্যবহারের মূল্যায়ন এবং কোড প্রোফাইলিংয়ের জন্য একটি এলোমেলোভাবে নমুনা জড়িত ঘড়ি আপনি কীভাবে সময়ের ব্যবধানগুলি সঠিকভাবে পরিমাপ করেছেন এবং "জেগে উঠেছে" তা দেখতে পরিশিষ্ট "অ্যাডভারসারি সোর্স কোড" এ একবার নজর রাখতে চাইবেন ঠিক সঠিক সময়ে তাদের প্রোগ্রাম। যেহেতু কোডটি 19 বছরের পুরাতন, সম্ভবত এটি সরাসরি বা সহজে পোর্ট হবে না তবে আপনি যদি এটি পড়েন এবং এটি বোঝার চেষ্টা করেন তবে জড়িত নীতিগুলি আপনার কোডকে গাইড করতে পারে।

সম্পাদনা: অন্য একটি রেফারেন্স পাওয়া গেছে যা সহায়তা করতে পারে: ইন্টারেক্টিভ এবং সফট রিয়েল-টাইম প্রক্রিয়াগুলির সময়সূচী সম্পর্কে ঘড়ির রেজোলিউশনের প্রভাব যা আপনাকে কোনও তাত্ত্বিক পটভূমিতে সহায়তা করবে।


4

ন্যানোস্লিপ () থেকে দেখুন ( http://linux.about.com/library/Cmd/blcmdl2_nanosleep.htm থেকে )। আপনার প্রোগ্রামটি 1 সেকেন্ডে ঘুমানোর পরিবর্তে, এটি সেকেন্ডে ঘুমান (1 - এটি চালাতে সময় লাগে) make আপনি একটি আরও ভাল রেজোলিউশন পাবেন।


আপনি নিয়মিত sleep, অর্থাত্ একই কাজ করতে পারেন sleep 0.99। সমস্যাটি হ'ল এটি চালাতে যে পরিমাণ সময় লাগে তা ধ্রুবক থেকে অনেক দূরের এমনকি এমনকি এর গড় মানও সময়ের সাথে সাথে ওঠানামা করতে পারে।
দিমিত্রি গ্রিগরিয়েভ

3

ব্যাকগ্রাউন্ডে আপনার কমান্ডটি চালানোর চেষ্টা করুন যাতে এটি লুপের সময়কে এতটা প্রভাবিত করে না, তবে আপনি যদি দীর্ঘ সময়ের জন্য কোনও সঞ্চারতা না চান তবে এটি যথেষ্ট হবে না কারণ এর সাথে অবশ্যই কয়েকটি মিলিসেকেন্ড ব্যয় যুক্ত রয়েছে।

সুতরাং, এটি সম্ভবত আরও ভাল, তবে সম্ভবত এখনও যথেষ্ট ভাল নয়:

while [ true ]; do date "+%Y-%m-%d %H:%M:%S" & sleep 1; done | 
tee timelog-sleep.txt

আমার কম্পিউটারে এটি 20 মিনিটে বা প্রতি মিনিটে 0,1 এ 2 টি ত্রুটি দিয়েছে যা আপনার রানের তুলনায় মোটামুটি কম পাঁচগুণ উন্নতি।


সমস্যাটি sleep 1হ'ল এটি কমপক্ষে এক সেকেন্ড ঘুমানোর গ্যারান্টিযুক্ত - কখনই কম নয়। সুতরাং ত্রুটি জমে।
হাহামু

দুটি পৃথক কম্পিউটারের সময়ের ফলাফলের তুলনা করা অর্থহীন, যদি না আপনি নিজের সিস্টেমে মূল কোডটি চালান এবং অপের মতো একই ফলাফল না পান।
দিমিত্রি গ্রিগরিয়েভ

1

কুৎসিত তবে এটি কাজ করে। আপনার যদি এই ধরণের লুপের প্রয়োজন হয় তবে আপনার প্রোগ্রামটির নকশাটি পুনর্বিবেচনা করা উচিত। এটি মূলত পরীক্ষা করে যে বর্তমান পুরো দ্বিতীয়টি আগের চেক করা একটির সমান এবং দ্বিতীয়টির পরিবর্তনের পর থেকে ন্যানোসেকেন্ডগুলির সংখ্যা মুদ্রণ করে। নির্ভুলতা ঘুম দ্বারা প্রভাবিত হয় .001।

while true; do T=$( date +%s ); while [[ $T -eq $( date +%s ) ]]; do sleep .001; done; date "+%N nanoseconds late"; done

নির্ভুলতাটি মিলি সেকেন্ডে রয়েছে তবে শর্ত থাকে যে 'পে-লোড' date "+%N nanoseconds late"কেবল এক সেকেন্ডের চেয়ে বেশি সময় নেয় না। আপনি ঘুমের সময়কাল বাড়িয়ে সিপিইউ লোড কমিয়ে দিতে পারেন বা যদি আপনার সত্যিই কিছু মনে না হয় তবে কেবলমাত্র ঘুম কমান্ডটি প্রতিস্থাপন করুন true

002112890 nanoseconds late
001847692 nanoseconds late
002273652 nanoseconds late
001317015 nanoseconds late
001650504 nanoseconds late
002180949 nanoseconds late
002338716 nanoseconds late
002064578 nanoseconds late
002160883 nanoseconds late

এটি খারাপ অভ্যাস কারণ আপনি মূলত কোনও ইভেন্টের জন্য আপনাকে সিপিইউ পোল তৈরি করেন এবং আপনি সিপিইউ চক্র নষ্ট করছেন। আপনি সম্ভবত একটি টাইমার বিঘ্ন (বাশ থেকে সম্ভব নয়) এর সাথে সংযুক্ত করতে বা মাইক্রোকন্ট্রোলারের মতো ডেডিকেটেড হার্ডওয়্যার ব্যবহার করতে চান। একটি পিসি এবং এর অপারেটিং সিস্টেমটি উচ্চ সময়ের সঠিকতার জন্য ডিজাইন করা হয়নি।


1

অন্য পদ্ধতিটি হ'ল লুপে সাসপেন্ড ব্যবহার করা এবং একটি সুনির্দিষ্ট বাহ্যিক প্রোগ্রাম থেকে সিগনকন্ট প্রেরণ করা। সিগন্যাল প্রেরণ করা খুব স্বল্প ওজনের এবং কোনও কিছু কার্যকর করার চেয়ে অনেক কম বিলম্ব হবে। আপনি "এট" কমান্ডের সাথে একগুচ্ছ কমান্ডগুলির প্রাক-কাতারেও যেতে পারতেন, আর কেউই "এট" ব্যবহার করেন না, আমি নিশ্চিত নই যে এটি কতটা সঠিক।

যদি যথার্থতা গুরুতর হয় এবং আপনি এই সম্পর্কে গুরুতর হতে চান, তবে এটি আর্টস-প্রিমিট প্যাচ করা কার্নেলের সাহায্যে লিনাক্সের অধীনে আরটিওএস ব্যবহার করতে পারে এমন অ্যাপ্লিকেশনটির মতো মনে হচ্ছে, যা আপনাকে যথার্থতা এবং কিছু পরিমাপের ব্যবস্থা করবে বিঘ্নিত নিয়ন্ত্রণ, তবে এটি এর চেয়ে মূল্যবান হতে পারে।

https://rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO

জেনোমাইও সহায়ক হতে পারে, এটি একটি সম্পূর্ণ আরটিওএস বাস্তবায়ন এবং x86 এবং x86_64 এর জন্য পোর্ট করা হয়েছে তবে এতে কিছু প্রোগ্রামিং জড়িত রয়েছে।

http://www.xenomai.org/index.php/Main_Page


1

সহ ksh93(যার একটি ভাসমান পয়েন্ট $SECONDSএবং একটি বিল্টিন রয়েছে sleep)

typeset -F SECONDS=0
typeset -i i=0
while true; do
   cmd
   sleep "$((++i - SECONDS))"
done

একই স্ক্রিপ্ট zshপাশাপাশি কাজ করবে কিন্তু আপনার সিস্টেমের sleepআদেশকে অনুরোধ করবে । zshএকটি zselectবিল্টিন রয়েছে তবে কেবল 1/100 রেজোলিউশন সহ।


0

আমি একটি ছোট সি প্রোগ্রাম নিয়ে যাব:

#include <sys/time.h>
#include <unistd.h>

int main(int argc, char **argv, char **envp)
{
    struct timeval start;
    int rc = gettimeofday(&start, NULL);
    if(rc != 0)
            return 1;

    for(;;)
    {
        struct timeval now;
        rc = gettimeofday(&now, NULL);
        useconds_t delay;
        if(now.tv_usec < start.tv_usec)
            delay = start.tv_usec - now.tv_usec;
        else
            delay = 1000000 - now.tv_usec + start.tv_usec;
        usleep(delay);
        pid_t pid = fork();
        if(pid == -1)
            return 1;
        if(pid == 0)
            _exit(execve(argv[1], &argv[1], envp));
    }
}

এই প্রোগ্রামটি প্রত্যাশা করে যে প্রোগ্রামটি প্রথম পথ হিসাবে তার প্রথম যুক্তি হিসাবে কল করবে এবং কোনও অবশিষ্ট আর্গুমেন্টে চলে passes কমান্ডটি শেষ হওয়ার জন্য অপেক্ষা করবে না, তাই এটি আনন্দের সাথে একাধিক উদাহরণ শুরু করবে।

এছাড়াও, এখানে কোডিং শৈলীটি সত্যই opালু, এবং প্রচুর অনুমান করা হয় যা প্রযোজ্য মান দ্বারা গ্যারান্টিযুক্ত হতে পারে বা নাও পারে, অর্থাত্ এই কোডটির গুণমান "আমার পক্ষে কাজ করে"।

এই প্রোগ্রামটি কিছুটা দীর্ঘ বা সংক্ষিপ্ত বিরতি পাবে যখন এনটিপি দ্বারা বা ম্যানুয়ালি সেট করে ঘড়িটি সামঞ্জস্য করা হবে। প্রোগ্রামটি যদি এটি পরিচালনা করে তবে পসিক্স এটি সরবরাহ করে timer_create(CLOCK_MONOTONIC, ...)যা এর দ্বারা প্রভাবিত নয় is


0

আপনার এখনকার সময়ের ট্র্যাক রাখা এবং এটি শুরু সময়ের সাথে তুলনা করা উচিত। সুতরাং আপনি প্রতিটি পুনরাবৃত্তির জন্য গণনা করা সময়ের পরিমাণ নির্ধারণ করেন, একটি নির্দিষ্ট পরিমাণ নয়। এইভাবে আপনি সময়সীমার ত্রুটিগুলি জড়ো করতে পারবেন না এবং আপনাকে যেখান থেকে হওয়া উচিত সেখান থেকে সরে যাবেন কারণ আপনি প্রতিটি লুপটি শুরু থেকে পরম সময়ে পুনরায় সেট করে।

এছাড়াও কিছু স্লিপ ফাংশন যদি কোনও ইন্টারুপ্ট থাকে তবে তাড়াতাড়ি ফিরে আসে, সুতরাং এক্ষেত্রে আপনাকে পুরো সময় ব্যয় না করা পর্যন্ত আপনার ঘুমের পদ্ধতিটি আবার কল করতে হবে।


0

এখানে একটি যা বাশ স্ক্রিপ্ট এবং অত্যন্ত নির্ভুল। এটি মাইক্রোসেকেন্ড নির্ভুলতার জন্য ঘুম ব্যবহার করে।

http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron

সেখানে 3 টি স্ক্রিপ রয়েছে। নীচে এক তাকান। যুক্তিসঙ্গত নির্ভুলতার সাথে প্রতি মিনিটে প্রায় 2400 মৃত্যুদণ্ড কার্যকর করা হবে। এবং এটি সত্যিই সহজ।


0

এই এক খুব নির্ভুল রেজোলিউশনের সাথে সেকেন্ডে কমপক্ষে 100 বার চালাতে পারে।

প্রতি মিনিটে লুপের সংখ্যার ডিরেক্টরিটির অস্তিত্ব সময়সূচী তৈরি করে। এই সংস্করণটি মাইক্রোসেকেন্ড রেজোলিউশনটিকে সমর্থন করে আপনার কম্পিউটার এটি পরিচালনা করতে পারে um প্রতি মিনিটে মৃত্যুদন্ড কার্যকর করার জন্য by০ দ্বারা সমানভাবে বিভাজন করতে হবে না বা এটি 60০ এর মধ্যে সীমাবদ্ধ নয় আমি এটি পরীক্ষা করেছি 6০০০ এবং এটি কাজ করে।

এই সংস্করণটি /etc/init.d ডিরেক্টরিতে ইনস্টল করা যায় এবং পরিষেবা হিসাবে চালানো যেতে পারে।

#! /bin/sh

# chkconfig: 2345 91 61
# description: This program is used to run all programs in a directory in parallel every X times per minute. \
#              Think of this program as cron with microseconds resolution.

# Microsecond Cron
# Usage: cron-ms start
# Copyright 2014 by Marc Perkel
# docs at http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron"
# Free to use with attribution

# The scheduling is done by creating directories with the number of"
# executions per minute as part of the directory name."

# Examples:
#   /etc/cron-ms/7      # Executes everything in that directory  7 times a minute
#   /etc/cron-ms/30     # Executes everything in that directory 30 times a minute
#   /etc/cron-ms/600    # Executes everything in that directory 10 times a second
#   /etc/cron-ms/2400   # Executes everything in that directory 40 times a second

basedir=/etc/cron-ms

case "$1" in

   start|restart|reload)
   $0 stop
   mkdir -p /var/run/cron-ms
   for dir in $basedir/* ; do
      $0 ${dir##*/} &
   done
   exit
   ;;

   stop)
   rm -Rf /var/run/cron-ms
   exit
   ;;

esac

# Loops per minute is passed on the command line

loops=$1
interval=$((60000000/$loops))

# Just a heartbeat signal that can be used with monit to verify it's alive

touch /var/run/cron-ms

# After a restart the PIDs will be different allowing old processes to terminate

touch /var/run/cron-ms/$$

# Sleeps until a specific part of a minute with microsecond resolution. 60000000 is full minute

usleep $(( $interval - 10#$(date +%S%N) / 1000 % $interval ))

# Deleting the PID files exit the program

if [ ! -f /var/run/cron-ms/$$ ]
then
   exit
fi

# Run all the programs in the directory in parallel

for program in $basedir/$loops/* ; do
   if [ -x $program ] 
   then
      $program &> /dev/null &
   fi
done

exec $0 $loops
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.