2016-05-31 5 views
0

C++コードを特定の時間実行して実行を終了する前に文を完成させたい。たとえば、プログラムの実行に関する次のシナリオを考えてみます。事前にC++コードの実行時間を設定する

0でカウンタを初期化します。実行時間がxミリ秒に等しい場合は、カウンタの現在の値を出力し、それ以外の場合は1をインクリメントします。実は、私は2つの最適化ALGORを比較したい

#include<iostream> 
using namespace std; 

int main(){ 
    int c=0; 
    while(true){ 
     /* do something to check the execution time, 
     if it is equal to x milliseconds print the value of c and exit*/ 

     c++; 
    } 
    return 0; 
} 

上記の課題は、C++のコードに何かを書き込むことによって達成される可能性があります同じ時間に実行された場合にどれくらいの最適解が得られるかに基づいて、特定の問題に対してC++で実装されています。

私はインターネットで検索しましたが、私が実際に望むものを得ることができませんでした。スレッドベースのソリューションがあるように見えますが、スレッドが非常に必要でない限り、スレッドを関与させたくありません。問題がC++の一部の機能だけで解決できるのであれば好都合ですが、C++コードを呼び出すシェルスクリプトがトリックを行う場合は大丈夫です(私はLinuxシステム上でコードを実行する可能性が高いです)。どんな助けもありがとう!

+3

これまで(あなたの宿題の説明は別として)何をしていましたか? – xxbbcc

+1

[計算の進捗状況を報告する]方法をお探しですか?(http://stackoverflow.com/questions/20586968/using-a-thread-in-c-to-report-progress-of-computations) – Matsmath

+4

'# ' –

答えて

0

いいえ古いのはどうですか?alarmssignals

#include <unistd.h> 
#include<iostream> 
using namespace std; 

void catchAlarm(int sig) { 
    std::cerr << "You will now die, Mr Bond!!\n"; 
    exit(-1); 
} 

int main(){ 
    int c=0; 

    // Die in 2 seconds.... 
    signal(SIGALRM, catchAlarm); 
    alarm(2); 

    while(true){ 
     /* do something to check the execution time, 
     if it is equal to x milliseconds print the value of c and exit*/ 
     c++; 
    } 
    return 0; 
} 

EDIT:上記の定型コードを使用すると、C++ 14あなたは、単に閉鎖でそれをキャプチャして、クロージャを使用することができますを使用しているがために、あなたは内部状態のいずれかを印刷することはできません。しかし

#include <stdlib.h> 
#include <unistd.h> 
#include <signal.h> 
#include <iostream> 
#include <functional>  
using namespace std; 

std::function<void()> myClosure; // The closure needs to be accessible to the alarm-function 
void catchAlarm(int sig) { 
    myClosure(); 
    exit(-1); 
} 

int main(){ 
    int c=0; 

    myClosure = [&]()->void{ 
     std::cerr << "You will now die at age " << c << "\n"; 
    }; 

    // Die in 2 seconds.... 
    signal(SIGALRM, catchAlarm); 
    alarm(2); 

    while(true){ 
     /* do something to check the execution time, 
     if it is equal to x milliseconds print the value of c and exit*/  
     c++; 
    } 
    return 0; 
} 

のように、内部に掘るために(これはあなたのケースに応じて、大きなしかしまたは小さなものであってもよい)、シグナルはカーネルによってトリガされ、それが半分ながら含め、いつでも実行することができます。コンパイラが順番に実行していたコードを使っていましたが、現在はアラームが途中で中断されていません。あなたのケースでは、何か面白い出力が最悪の場合には問題ありませんが、ラムダがオブジェクトを修正している場合は、スレッドセーフでないコードに似た問題が発生する可能性があります。

+0

これは私が探していたもののようです!ちょうど2点:1.ヘッダ 'alarm.h 'はうまくいかず、' unistd.h'と 'signal.h'をインクルードする必要がありました。2.' catchAlarm'関数を使って ' 'c'をグローバル変数にせずに' c'を実行しますか? –

+0

もちろん、C++ 14を使用しているので、ラムダ関数で興味深いものをキャプチャし、シグナルハンドラから呼び出すことができます。上記の例を追加しました。gnu g ++を使用している場合は、ラムダ機能が有効になる前にオプションとしてg ++ -std = C++ 14'(または-std = C++ 11)を指定してください – Soren

+0

シグナルハンドラでは何ができるのですか? 'std :: function'を呼び出すことはそれらの一つではありません。 'std :: cerr'にも出力していません。 –

1

問題を解決するには、コードがどの程度正確に構成されているか、そして正確に計算を実行する方法についてのより詳細な分析が必要です。可能な解決策は次のとおりです。

別のスレッドで実行するように計算コードを移動します。 <thread>を使用してスレッドを作成できます。加算スレッドの引数を計算スレッドに渡すか、グローバルにします(例:std::atomic<bool> time_s_up)。あなたがスレッドを開始した後、メインスレッドで

void compute(std::atomic<bool> &time_is_up) 
{ 
    while (!time_is_up) { 
     c++; 
    } 
} 

あなたはあなたがた後、スリープやタイマーを使用することができます:あなたのコードは次のようになります

int main() 
{ 
    std::atomic<bool> time_s_up = false; 
    std::thread t(compute, time_s_up); 
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); 
    time_s_up = true; 
    t.join(); 
} 

別の解決策(1あなた実際に考える)も良いですが、c++文は、より複雑な計算なので、時間を取得するための呼び出しはわずかなオーバーヘッド相当するであろう時にのみ:ヨーヨー場合

// auto g_start = std::chrono::high_resolution_clock::now(); 
// g_time - total number of milliseconds to run 
while (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - g_start).count() <= g_time) { 
    some_complex_iteration_computations(); 
} 

を他の方法(例えばtimeoutや他の回答で提案されているようなアラーム)を使うと、killシグナルが現在の結果を出力することなくプログラムを終了させるだけなので、部分的な結果を追跡する必要があります。

+0

私はこれらのソリューションを使わないとできない場合、これらのソリューションを試してみます。私はスレッドを使用することに少し消極的です。 –

+0

@SnehasishKarmakar、なぜスレッドは問題ですか? – kaspersky

+0

スレッドに問題はありません。コード自体はすでに複雑なので、もっと複雑にならないようにしたいだけです。 –

2

あなたはtimeout(1)を探しています。

もしあなたがC++でやっているのであれば(私はスクリプトの方が良いと思います。プログラムが一つのことを行い、リソースが極限に制限されていない限りうまくやってください)、古典的なUNIXソリューションはalarm(2)ですいくつかの新しいタイマーがあるにもかかわらず、タイムアウトに基づいている可能性があります)。

タイムアウト後にプログラムを終了させる以外の操作を行う場合は、SIGALRM信号のハンドラを設定する必要があります。

+0

'timeout'は実際に要件を満たしていません。あなたの最後の声明で)。 「警報」は完璧だと思われる。 –

0

alarmはすばらしい解決策です。

ここで私はばかだが簡単な解決法を提供します。

// c code 
int main(int argc, char ** argv[]) { 
    for (int i = 1; ; ++i) { 
     // do something 
     printf("%d\n", i); 
    } 
} 

この方法でプログラムを実行します。

#!/bin/bash 
./a.out & 
sleep 2s && kill $(jobs -p) 
+0

私はこれを正確に必要としません。私は、プログラムが終了する直前に(指定された時間制限を超えて)最新の結果を印刷するようにしたい。 –

+0

@SnehasishKarmakarちょうど追加する|テール-1 – pjincz

関連する問題