ウォッチ漫画『酒男子』新連載開始!

VCでウエイトをミリ秒単位でかけられるんですが、μ秒でのやり方わかりません。

Sleep(); や タイマーでウエイトをミリ秒単位でかけられます。
どうしても、μ秒でウエイトをかけて、CPUを軽くしたいのです。
μ秒単位のウエイトのかけ方を教えてください。

理由:whileでずっと、ある処理を続けていたいのですが、CPUが100%にいってしまい。他のアプリが重いです。かといって、ミリ秒単位ででウエイトをかけても、処理の方に問題がでてしまいます。

このQ&Aに関連する最新のQ&A

A 回答 (6件)

μ秒オーダーで処理を OS に戻すやり方は


分かりませんが、
永久ループしている中で何回かに1回 Sleep(1)
するのも手ですよ。
    • good
    • 0

Perntium以降のCPUに限りますが・・・


QueryPerformanceCounter()
QueryPerformanceFurequency()
にてCPUのクロックカウントを取得できます
これを使えばマイクロ秒単位でも計測は出来ます・・・が
理由を見る限りではこの方法でどうこうするよりも構造を見直すか、マルチスレッド化したりするほうが上手くいくと思いますよ

QueryPerformanceCounter()
http://www.microsoft.com/japan/developer/library …

QueryPerfonmanceFrequency()
http://www.microsoft.com/japan/developer/library …
    • good
    • 0

 もし、正確な間隔が必要ないなら



 sleep(0);

 を試してみてはいかがでしょう。
 CPU使用率は100%近くになりますが、他のアプリはそれほど重く
ないと思います。
    • good
    • 0

基本的にWindowsのAPIの類ではマイクロ秒単位で


Sleepさせることはできなかったはず・・・

どうしてもというのであれば、C言語でサポート
していたと思うので、そちらを探してください。

それと、while文でずっと処理を回し続ければ、
当たり前ですが、やたらとCPUの処理を占有すると
思います。どうせGUIを持つのでしょうから、
タイマーをはってはどうでしょうか?CUIのものの
場合は、見せないWindowを作れば、同じような
動作が可能になるはずです。

タイマーが切れたら処理をして、一度終わったら
また数ミリ秒待たせる・・・
これではダメですか?

どのような処理をさせたいのか分かりませんが、
ある程度のものならば、これで対処できると思います。

ダメなときは補足してください。
ではでは☆
    • good
    • 0

これは、μ秒でやってもCPU負荷は100%になりますよ。


Windowsプログラムは、OSを含むプロセス間でメッセージ等の
通信をしていますので、あるプログラムがこのプロセス通信を遮断すると、
他のアプリの通信が途絶えます。よって、他のアプリが重くなるのです。
くわしくは、OSはそれぞれのプログラムが何をやってるかわかりませんから、
容赦なく全てのプログラムにメッセージを送ってきます。
プログラムは、そのメッセージが必要なければ、必要ない旨をOSに
知らせなくてはなりません。whileループでこの処理を行っていない場合、
OSはタイムアウトまで待ちつづけることになり、他のプログラムに
メッセージを送れません。当然、本来そのメッセージが必要なプログラム側
からすれば、メッセージがこないわけですから動くことが出来ません。

ある処理を続けたいのならば、その処理をスレッド処理をするか、
その処理内部でメッセージ処理をするようにしましょう。
    • good
    • 0
この回答へのお礼

ご返答ありがとうございました(^0^)

またよろしくお願いします

お礼日時:2001/01/26 12:17

μ秒単位ウェイトは無理です。


 ミリ秒単位が限界です。1/16秒が限界で、それ以下にしても、期待したスペックは出ません。

 重い処理の場合には、スレッドにするのが一般的で、それならばスレッドの優先度等を設定すれば、CPUが100%にならずに使用出来ます(まぁ設計の問題があれば別ですが...ね)
    • good
    • 0
この回答へのお礼

ご返答ありがとうございました(^0^)

またよろしくお願いします

お礼日時:2001/01/26 12:17

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Qsleep()関数について

"数秒おきに警報をn回鳴らすプログラム"をC言語で作成しようと
考えています。

プログラム実行環境はWindowsですが、
sleep()関数は使用できないのでしょうか??

仮に使用できない場合、この関数に代わる関数や代替方法が
あれば教えて頂けませんでしょうか? 宜しくお願いします。

Aベストアンサー

正確な動作でも構わなければ
windows.hをインクルードして
Sleep()関数を使いましょう.
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200207/02070061.txt

しかし,正確に数秒おきに動作を行いたい場合はマルチメディアタイマ等を使いましょう.
マルチメディアタイマはミリ秒間隔でコールバック関数を呼び出すことができます.
timeSetEventを用いてコールバック関数の登録を行うことができます.
timeKillEventでコールバック関数の解除を行うことができます.

多分他にも方法があると思うのですが…私はこれぐらいしか知りません^^;

参考URL:http://www.katto.comm.waseda.ac.jp/~katto/Class/GazoTokuron/code/time.html

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qマイクロ秒で精度が出るタイマー

マイクロ秒で精度が出るタイマーってご存知ではないでしょうか?
ご存知ならご教授おねがいします。

・環境
OS:XP
使用言語:C、C++
その他:API32使用

よろしくお願いします。

Aベストアンサー

>実は業務で連続的に16bitのデータを送る通信システムを作成しているのですが、その送信するデータとデータの間のインターバル的な時間をマイクロ秒単位で管理したいのです。
>守秘義務が絡むのであまり詳しくお話できなくて申し訳ありません。。。

インターバルタイムが最低限の時間(オーバーを許容)なら問題ないと思いますが、そのインターバルタイムを死守しないとマズイならWindowsOSでは無理ですので、別のOSで特にリアルタイム性がメインのリアルタイムオペレーティングシステム(RTOS)を捜すべきだと思います。
http://ja.wikipedia.org/wiki/%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0

インターバルタイムのオーバーが許容されても、QueryPerformanceCounterとPerformanceCounterは最近のCPUのターボ・ブーストなどのためで不正確になっています。
ターボ・ブーストとは。
http://www.pasonisan.com/customnavi/cpu_corei/10tuboboost.html
最近のCPUの場合はこのターボ・ブーストの動作状況次第でQueryPerformanceCounterの値が実際の経過時間とズレてしまうのです。
なので、ブーストしないCPUなどの選択も考えないといけないでしょう。

QueryPerformanceCounterを実時間計測には使えない
http://d.hatena.ne.jp/shiku_otomiya/20100218/p1

あるいは、タイマカウントーを外部のマイコンに任せるとか通信自体を外部のマイコンにさせるとかすれば正確な動作は期待できます。

>実は業務で連続的に16bitのデータを送る通信システムを作成しているのですが、その送信するデータとデータの間のインターバル的な時間をマイクロ秒単位で管理したいのです。
>守秘義務が絡むのであまり詳しくお話できなくて申し訳ありません。。。

インターバルタイムが最低限の時間(オーバーを許容)なら問題ないと思いますが、そのインターバルタイムを死守しないとマズイならWindowsOSでは無理ですので、別のOSで特にリアルタイム性がメインのリアルタイムオペレーティングシステム(RTOS)を捜すべきだと思...続きを読む

QをVisualStudioでつかえるようにする

<unistd.h>をVisualStudioでつかえるようにしたいのですが、問題なくコンパイルできるようにするにはどうしたらいいでしょうか?

CygwinというやつをインストールしてやってみたのですがやはりVisualStudioだけでコンパイルしてやりたいのですが。。。。

Aベストアンサー

おそらく<unistd.h>をフルスペックで利用したいわけではないと思います。その中の一部の関数を使いたいだけなら<io.h>などで代用できるはずですから、ヘルプで調べてみることをお勧めします。

ソースを修正せずに、コンパイル&実行ができるようにすることは諦めた方がよいと思います。

移植のことを考えるなら、<unistd.h>とか<windows.h>のような環境に特化したヘッダや、そこで宣言される型や関数などを直接使うのではなく、適切にラッピングしてから使う方が後々楽です。今回は仕方ないでしょうが、今後はそうしましょう。

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

Qmsec単位のWait Timerが作れない!

引数で渡した値だけ待つ関数を作っているのですが、うまくいきません。

OS:WindowsXP Professional (SP1)
プラットホーム:Visual C++ Ver7
アプリケーション:コンソールタイプ

失敗例1:Sleep()関数を用いた。
結果:15msec以下の設定が出来なかった。
(1/64secの整数倍でないとズレが生じた)

失敗例2:Clock()関数を使って以下のルーチンを作成

void WaitTimer( clock_t wait )
{
register clock_t goal;
goal = clock() + wait;
while( goal > clock());
}
結果:失敗例1と同じ結果。

どうやら(スレッドか何かはわかりませんが)64Hz周期の何かがあるようです。
 
何方か10msec単位(±1msec)のWaitTimerを作ったことがある方、是非ノウハウを教えてください!

Aベストアンサー

既に2の方が回答されていますが

QueryPerformanceCounterとQueryPerformanceFrequencyが
最も高い時間精度を持つ測定用のAPIです。
(GetTickCount等に比べると1回の処理自体は重いです。)

http://homepage1.nifty.com/aok2/04oldpage/win01.html

あと少しでもパフォーマンスをよくするなら
inline展開してはどうでしょう。
inline void WaitTimer( DWORD wait )
{
(略)
}

QueryPerformanceCounter自体にも処理がかかるので
事前にそれらの処理にかかる時間を計算しておき
その値を差し引くとより厳密になるかもしれません。


http://www14.big.or.jp/~ken1/tech/tech19.html

参考URL:http://homepage1.nifty.com/aok2/04oldpage/win01.html,http://www14.big.or.jp/~ken1/tech/tech19.html

既に2の方が回答されていますが

QueryPerformanceCounterとQueryPerformanceFrequencyが
最も高い時間精度を持つ測定用のAPIです。
(GetTickCount等に比べると1回の処理自体は重いです。)

http://homepage1.nifty.com/aok2/04oldpage/win01.html

あと少しでもパフォーマンスをよくするなら
inline展開してはどうでしょう。
inline void WaitTimer( DWORD wait )
{
(略)
}

QueryPerformanceCounter自体にも処理がかかるので
事前にそれらの処理にかかる時間を計算しておき
その値を差し引くと...続きを読む

Qsleep関数の精度について

こんにちは。
この掲示板やみなさまには、大変お世話になっています。ありがとうございます。

そこで、質問ですが、

sleep関数を用いて、スレッドを一時停止させたりしたいのですが、sleep関数の精度はどれくらいあるのでしょうか?

1msの精度を出すことはできるのでしょうか・・・
Sleep(1)とSleep(10)では、違いが無いような気がします。
そもそも、無理なことでしょうか?

よろしくお願いします。

Aベストアンサー

環境が分からないので正確なことは何も分かりませんが...

> sleep関数の精度はどれくらいあるのでしょうか?

POSIXのsleep関数のことであれば、引数を1秒単位でしか指定できないので、1msの精度を出すことはそもそも無理です。
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/sleep.3.html

> Sleep(1)とSleep(10)では、違いが無いような気がします。

Win32 APIのSleepは1ms単位で指定しますが、それほど高い分解能はありません。
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdllpro/html/_win32_sleep.asp

QC# シリアル通信でデータ受信時の欠損について

Visualstudio 2013 を使用して C# で開発を行っています。

SerialPort Classを使用してデータの送受信をするプログラムを作成しているのですが、
非同期でデータを受信する際にどうしてもうまくデータを取得出来ません。

5Byteのデータは正常に取得できるのですが、
その直後にくる40Byteのデータは、真ん中あたりの10数Byteや最後の10数Byteしか取れません。


serialPort.DataReceived に登録したイベント関数の中身です。

--------------------------------------------------------------------------------------
private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
bytesRead = 0;
// Initialize a buffer to hold the received data
byte[] buffer = new byte[this.serialPort.ReadBufferSize];

try
{
bytesRead = this.serialPort.Read(buffer, 0, buffer.Length);
if (true == serialPort.IsOpen)
{
serialPort.DiscardInBuffer();//受信バッファをクリアする
}

}
catch (Exception ex)
{
DataLog.Exception(ex);
}

//派生クラス用の処理
DeviceClassEventArgs _DeviceClassEventArgs = new DeviceClassEventArgs(buffer, bytesRead);
DeviceClassEvent(this, _DeviceClassEventArgs);
}
--------------------------------------------------------------------------------------

ネットの情報を参考に、
ReceivedBytesThreshold の値を期待するデータ量に逐一変えることで
とりあえず正常に取ることが出来たのですが、これでいいのでしょうか?
期待するデータ量がわからなかった場合は使えないのかなとも思います。

データが欠損してしまう理由、
上記の対処法以外の一般的な対処法など有りましたら教えて下さい。

その他参考になるページ等ありましたら教えていただけると大変助かります。

Visualstudio 2013 を使用して C# で開発を行っています。

SerialPort Classを使用してデータの送受信をするプログラムを作成しているのですが、
非同期でデータを受信する際にどうしてもうまくデータを取得出来ません。

5Byteのデータは正常に取得できるのですが、
その直後にくる40Byteのデータは、真ん中あたりの10数Byteや最後の10数Byteしか取れません。


serialPort.DataReceived に登録したイベント関数の中身です。

-------------------------------------------------------------------------------...続きを読む

Aベストアンサー

DataReceivedイベントが発生したときでも、
シリアルポートへの受信はまだ継続している可能性があるので
不用意にバッファクリアしてはいけない。
非同期の受信処理は、何かと難しいのです。

private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
  bytesRead = 0;
  // Initialize a buffer to hold the received data
  byte[] buffer = new byte[this.serialPort.ReadBufferSize];

  try
  {
    //bytesRead = this.serialPort.Read(buffer, 0, buffer.Length);
    //if (true == serialPort.IsOpen)
    //{
    // serialPort.DiscardInBuffer();//受信バッファをクリアする
    //}

    // 受信バッファにデータがなくなるまで繰り返し読込む
    while (true)
    {
      if (0 == serialPort.BytesToRead)
      {
        break;
      }
      buffer[bytesRead] = (byte)serialPort.ReadByte();
      bytesRead++;
      System.Threading.Thread.Sleep(0);

      // シリアルポートの受信バッファには、
      // ・必要なブロックの途中から受信している。
      // ・次のブロックの先頭部分も受信されている。
      // 可能性があるので、ここで必要なブロックだけRead()できたことを確認する。
      if (必要なブロックが正常に読めたか確認する関数())
      {
        break;
      }
    }
  }
  catch (Exception ex)
  {
    DataLog.Exception(ex);
  }

  //派生クラス用の処理
  DeviceClassEventArgs _DeviceClassEventArgs = new DeviceClassEventArgs(buffer, bytesRead);
  DeviceClassEvent(this, _DeviceClassEventArgs);
}

DataReceivedイベントが発生したときでも、
シリアルポートへの受信はまだ継続している可能性があるので
不用意にバッファクリアしてはいけない。
非同期の受信処理は、何かと難しいのです。

private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
  bytesRead = 0;
  // Initialize a buffer to hold the received data
  byte[] buffer = new byte[this.serialPort.ReadBufferSize];

  try
  {
    //bytesRead = this.serialPort.Read(buffer, 0, buffer.Le...続きを読む

QLPCWSTRとchar

質問なのです・・・

現在、私は[Visual Stdio.Net 2005]を使って、C++のプログラミングをしようと思いまして、今日参考書を見てやってみたのですが、

charの配列を使って、文字列を格納しそれを使おうとしたら、LPCWSTRのキャストが必要というエラーがでました。
参考書だと普通に通るらしいのですが・・・Visual Stdio.Net 2003と2005の違いなのでしょか?わかる方教えていただけませんでしょうか??

Aベストアンサー

補足です。
2005デフォルトのUNICODEを変更する方法は
プロジェクト->プロパティ->構成プロパティ->全般 の中にある
文字セットを[Unicode 文字セットを使用する]から[マルチバイト文字セットを使用する]
に変更することで可能です。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング