iOS 上的 POSIX 线程
我已经开始使用 ios 平台尝试 POSix 线程。使用 NSThread 是相当令人畏惧的。
基本上在我的示例应用程序中,我有一个充满 mystruct 类型的大数组。每隔一段时间(非常频繁),我想在后台中使用这些结构之一的内容执行一项任务,因此我将其传递给 detachnewthread 以开始工作。
我想我已经掌握了基础知识,但在尝试继续更复杂的事情之前,我想获得专业意见。 我这里的东西看起来“没问题”吗?你能指出任何可能导致问题的遗漏吗?你能发现任何内存管理问题等......
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);
}
I've started experimenting with POSix threads using the ios platform. Coming fro using NSThread it's pretty daunting.
Basically in my sample app I have a big array filled with type mystruct. Every so often (very frequently) I want to perform a task with the contents of one of these structs in the background so I pass it to detachnewthread to kick things off.
I think I have the basics down but Id like to get a professional opinion before I attempt to move on to more complicated stuff.
Does what I have here seem "o.k" and could you point out anything missing that could cause problems? Can you spot any memory management issues etc....
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一个潜在的问题是如何创建传入结构
mystruct
的存储。该变量的生命周期对其在线程中的使用非常关键。例如,如果 detachnewthread 的调用者在堆栈上声明了该声明,然后在线程完成之前返回,则这将是未定义的行为。同样,如果它是动态分配的,则有必要确保它在线程完成之前不会被释放。回应评论/问题:某种互斥体的必要性取决于用法。为了讨论的方便,我假设它是动态分配的。如果调用线程在创建“子”线程之前填充结构体的内容,并且可以保证直到子线程退出后才释放它,并且后续访问是只读的,那么您就不需要互斥体来保护它。如果该结构包含子线程完成其任务所需的信息,我可以想象这种类型的场景。
但是,如果有多个线程将访问该结构的内容并且一个或多个线程将更改数据(写入该结构),那么您可能确实需要一个互斥体来保护它。
One potential issue would be how the storage for the passed in structure
mystruct
is created. The lifetime of that variable is very critical to its usage in the thread. For example, if the caller ofdetachnewthread
had that declared on the stack and then returned before the thread finished, it would be undefined behavior. Likewise, if it were dynamically allocated, then it is necessary to make sure it is not freed before the thread is finished.In response to the comment/question: The necessity of some kind of mutex depends on the usage. For the sake of discussion, I will assume it is dynamically allocated. If the calling thread fills in the contents of the structure prior to creating the "child" thread and can guarantee that it will not be freed until after the child thread exits, and the subsequent access is read/only, then you would not need a mutex to protect it. I can imagine that type of scenario if the structure contains information that the child thread needs for completing its task.
If, however, more than one thread will be accessing the contents of the structure and one or more threads will be changing the data (writing to the structure), then you probably do need a mutex to protect it.
尝试使用 Apple 的 Grand Central Dispatch (GCD),它将为您管理线程。 GCD 提供通过块将工作分派到系统管理的各种队列的功能。一些队列类型是并发的、串行的,当然还有 UI 运行的主队列。根据现有的 CPU 资源,系统将管理队列和必要的线程来完成工作。一个简单的示例显示了如何将调用嵌套到不同的队列,如下所示:
__block MyClass *blockSelf=self 只是用来避免与块工作方式相关的保留循环。
苹果的文档:
http://developer.apple.com/ Library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
Mike Ash 的问答博客文章:
http://mikeash.com/pyblog/friday-qa-2009-08-28-intro-to-grand-central-dispatch-part-i-basics-and-dispatch-queues.html< /a>
Try using Apple's Grand Central Dispatch (GCD) which will manage the threads for you. GCD provides the capability to dispatch work, via blocks, to various queues that are managed by the system. Some of the queue types are concurrent, serial, and of course the main queue where the UI runs. Based upon the CPU resources at hand, the system will manage the queues and necessary threads to get the work done. A simple example, which shows the how you can nest calls to different queues is like this:
__block MyClass *blockSelf=self is used simply to avoid retain cycles associated with how blocks work.
Apple's docs:
http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
Mike Ash's Q&A blog post:
http://mikeash.com/pyblog/friday-qa-2009-08-28-intro-to-grand-central-dispatch-part-i-basics-and-dispatch-queues.html