0

クラスの初期化メソッドで、スレッドを次のように宣言しています。

NSThread* myThread = [[[NSThread alloc] initWithTarget:self selector:@selector(m_run_thread) object:nil] autorelease];
[myThread start]; 

NOに設定されたブール値もあります。コードの後半で、ブール値をYESに設定しました。

bool_run_progress_thread = YES;

メソッドm_run_threadの内容は次のとおりです。

-(void) m_run_thread
{
    if (bool_run_progress_thread)
    {
         //do processing here
     }

bool_run_progress_thread = NO;
}

問題は、メソッドm_run_threadがアクセスされないことです。私は何が間違っているのですか?

PS私はまた、次の(そして古い)方法を使用してスレッドを設定しようとしました:

[NSThread detachNewThreadSelector:@selector(m_run_thread) 
                         toTarget:self 
                       withObject:nil];

...しかし、同様に役に立たない。

4

1 に答える 1

2

「...そして私はそれを一度だけ表示させています」はい、それはまさにそれがどうあるべきかです。開始された後、スレッドは開始から終了まで1回実行され(ここではエラーを無視します)、終了に達すると、スレッドは本質的に停止してなくなります。

スレッドにその実行を繰り返させたい場合は、自分でその準備をする必要があります。

- (void) m_run_thread
{
    for (;;) 
    {
        if (bool_run_progress_thread)
        {
            //do processing here
            bool_run_progress_thread = NO;
        }
    }
}

しかし、このコードにはまだ多くの間違いがあります。基本的に、実行すると、コードはビジー待機ループを形成します。bool_run_progress_threadそれが短期間だけ当てはまると仮定すると、バックグラウンドスレッドはほとんどの時間スリープしているはずです。Inseadでは、コードをそのまま試してみると、代わりにCPU時間(およびその多く)を消費します。

これに対するより良いアプローチには、条件変数が含まれます。

@class Whatsoever 
{
    NSCondition* cvar;
    BOOL doProgress;
    ...
}
...
@end

- (void) m_run_thread
{
    for (;;) 
    {
        [cvar lock];

        while (!doProgress) 
        {
            [cvar wait];
        }

        doProgress = NO;
        [cvar unlock];

        ... do work here ...
    }
}

実行をトリガーするには、次のようにします。

- (void) startProgress 
{
    [cvar lock];
    doProgress = YES;
    [cvar signal];
    [cvar unlock];    
}

この方法で物事を行うと、別の微妙な問題も処理されます。グローバルフラグ(your bool_run_progress_thread、my doProgess)に加えられた変更の可視性です。プロセッサとそのメモリの順序に応じて、特別な保護なしで行われた変更は、他のスレッドに表示される場合と表示されない場合があります。この問題は、によっても処理されNSConditionます。

于 2012-05-17T12:27:11.730 に答える