我正在使用创建子线程的Pthreads编写C程序。创建子线程后,父线程应该输出两条消息:" parent:begin"然后它应该打印" parent:done"。儿童线程相同"孩子:开始"和孩子:完成"。我必须确保主线程在生成(子)线程之前打印他的第二条消息。我必须遵循实现,但它只打印错误的顺序。我想我应该使用旗帜。任何帮助将不胜感激。
<b:widget id='BlogArchive1' locked='false' title='' type='BlogArchive'>
<b:includable id='main'>
<b:if cond='data:title != ""'>
<h2><data:title/></h2>
</b:if>
<div class='widget-content'>
<div id='ArchiveList'>
<div expr:id='data:widget.instanceId + "_ArchiveList"'>
<b:include cond='data:style == "HIERARCHY"' data='data' name='interval'/>
<b:include cond='data:style == "FLAT"' data='data' name='flat'/>
<b:include cond='data:style == "MENU"' data='data' name='menu'/>
</div>
</div>
<b:include name='quickedit'/>
</div>
</b:includable>
<b:includable id='flat' var='data'>
<ul class='flat'>
<b:loop values='data:data' var='i'>
<li class='archivedate'>
<a expr:href='data:i.url'><data:i.name/></a> (<data:i.post-count/>)
</li>
</b:loop>
</ul>
</b:includable>
<b:includable id='interval' var='intervalData'>
<b:loop values='data:intervalData' var='interval'>
<ul class='hierarchy'>
<li expr:class='"archivedate " + data:interval.expclass'>
<b:include cond='data:interval.toggleId' data='interval' name='toggle'/>
<a class='post-count-link' expr:href='data:interval.url'>
<data:interval.name/>
</a>
<span class='post-count' dir='ltr'>(<data:interval.post-count/>)</span>
<b:include cond='data:interval.data' data='interval.data' name='interval'/>
<b:include cond='data:interval.posts' data='interval.posts' name='posts'/>
</li>
</ul>
</b:loop>
</b:includable>
<b:includable id='menu' var='data'>
<select expr:id='data:widget.instanceId + "_ArchiveMenu"'>
<option value=''><data:title/></option>
<b:loop values='data:data' var='i'>
<option expr:value='data:i.url'><data:i.name/> (<data:i.post-count/>)</option>
</b:loop>
</select>
</b:includable>
<b:includable id='posts' var='posts'>
<ul class='posts'>
<b:loop values='data:posts' var='post'>
<li><a expr:href='data:post.url'><data:post.title/></a></li>
</b:loop>
</ul>
</b:includable>
<b:includable id='toggle' var='interval'>
<a class='toggle' href='javascript:void(0)'>
<span expr:class='"zippy" + (data:interval.expclass == "expanded" ? " toggle-open" : "")'>
<b:if cond='data:interval.expclass == "expanded"'>
▼ 
<b:elseif cond='data:blog.languageDirection == "rtl"'/>
◄ 
<b:else/>
► 
</b:if>
</span>
</a>
</b:includable>
</b:widget>
答案 0 :(得分:2)
如果您希望父级首先打印done
,那么您应该让子线程旋转直到父级完成。 (现在父进程在等待子进程旋转。)你还应该使用pthread_join
来确保在主线程返回之前完成子进程:
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
volatile int done = 0;
void *child(void *arg) {
printf("child: begin\n");
while (done == 0); // spin
printf("child: done\n");
return NULL;
}
int main(int argc, char *argv[]) {
printf("parent: begin\n");
pthread_t c;
pthread_create(&c, NULL, child, NULL); // create child
printf("parent: done\n");
done = 1;
pthread_join(c, NULL);
return 0;
}
在我的机器上,我得到了这个输出:
parent: begin
parent: done
child: begin
child: done
答案 1 :(得分:0)
目前访问done
而两个线程没有任何同步。正确的方法是通过条件变量向孩子发出父母已完成打印的信号。这导致数据竞赛。
此外,main()线程在do之前完成执行。在这种情况下,整个过程将会死亡。您可以拨打pthread_join()
或只使用pthread_exit()
退出主线索。
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
volatile int done = 0;
void *child(void *arg) {
printf("child\n");
pthread_mutex_lock(&mutex);
while(done == 0)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
printf("child:done");
return NULL;
}
int main(int argc, char *argv[]) {
printf("parent: begin\n");
pthread_t c;
pthread_create(&c, NULL, child, NULL); // create child
pthread_mutex_lock(&mutex);
done = 1;
printf("parent: end\n");
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
pthread_exit(0);
}