0

在一个类的初始化方法中,我这样声明线程:

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

我还有一个设置为 NO 的布尔值。稍后在代码中,我将布尔值设置为 YES。

bool_run_progress_thread = 是;

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

“......我只让它展示一次”是的,这正是它应该的样子。启动后,线程从开始到结束运行一次(暂时忽略这里的错误),到达结束时,线程基本上已经死了。

如果您希望线程重复执行,您必须自己为此做好准备:

- (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];    
}

这样做还可以解决另一个微妙的问题:对全局标志(您的bool_run_progress_thread、我的doProgess)所做更改的可见性。根据处理器及其内存顺序,在没有特殊保护的情况下所做的更改可能会或可能不会(永远)对其他线程可见。这个问题也由NSCondition.

于 2012-05-17T12:27:11.730 回答