我开始使用ios平台试验POSix线程。使用NSThread回来时非常令人生畏。
基本上在我的示例应用程序中,我有一个填充了类型mystruct的大数组。每隔一段时间(非常频繁),我想在背景中使用其中一个结构的内容执行任务,因此我将其传递给detachnewthread以启动。
我认为我已经掌握了基础知识,但我希望在尝试转向更复杂的事情之前获得专业意见。 我在这里看到的是“o.k”,你能指出任何可能导致问题的遗漏吗?你能发现任何内存管理问题等......
struct mystruct
{
pthread thread;
int a;
long c;
}
void detachnewthread(mystruct *str)
{
// pthread_t thread;
if(str)
{
int rc;
// printf("In detachnewthread: creating thread %d\n", str->soundid);
rc = pthread_create(&str->thread, NULL, DoStuffWithMyStruct, (void *)str);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
//exit(-1);
}
}
//
/* Last thing that main() should do */
// pthread_exit(NULL);
}
void *DoStuffWithMyStruct(void *threadid)
{
mystruct *sptr;
dptr = (mystruct *)threadid;
// do stuff with data in my struct
pthread_detach(soundptr->thread);
}
答案 0 :(得分:1)
尝试使用Apple的Grand Central Dispatch(GCD),它将为您管理线程。 GCD提供了通过块将工作分派到由系统管理的各种队列的功能。一些队列类型是并发的,串行的,当然还有UI运行的主队列。根据手头的CPU资源,系统将管理队列和必要的线程以完成工作。一个简单的例子,它显示了如何将调用嵌套到不同的队列,如下所示:
__block MYClass *blockSelf=self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[blockSelf doSomeWork];
dispatch_async(dispatch_get_main_queue(), ^{
[blockSelf.textField setStringValue:@"Some work is done, updating UI"];
});
});
__ block MyClass * blockSelf = self仅用于避免与块如何工作相关的保留周期。
Mike Ash的Q& A博文: http://mikeash.com/pyblog/friday-qa-2009-08-28-intro-to-grand-central-dispatch-part-i-basics-and-dispatch-queues.html
答案 1 :(得分:1)
一个潜在的问题是如何创建传入结构mystruct
的存储空间。该变量的生命周期对其在线程中的使用非常关键。例如,如果detachnewthread
的调用者在堆栈上声明了然后在线程完成之前返回,则它将是未定义的行为。同样,如果它是动态分配的,那么有必要确保在线程完成之前不释放它。
回应评论/问题:某种互斥体的必要性取决于使用情况。为了便于讨论,我将假设它是动态分配的。如果调用线程在创建“子”线程之前填充结构的内容,并且可以保证在子线程退出之后它不会被释放,并且后续访问是只读的,那么您将不需要用于保护它的互斥体。如果结构包含子线程完成其任务所需的信息,我可以想象这种类型的场景。
但是,如果多个线程将访问结构 和 的内容,则一个或多个线程将更改数据(写入结构),那么你可能需要一个互斥锁来保护它。