??xml version="1.0" encoding="utf-8" standalone="yes"?>国内精品久久久久影院亚洲,久久精品亚洲中文字幕无码麻豆,国产精品无码久久综合http://www.shnenglu.com/izualzhy/archive/2011/11/14/160123.htmlizualzhyizualzhyMon, 14 Nov 2011 14:47:00 GMThttp://www.shnenglu.com/izualzhy/archive/2011/11/14/160123.htmlhttp://www.shnenglu.com/izualzhy/comments/160123.htmlhttp://www.shnenglu.com/izualzhy/archive/2011/11/14/160123.html#Feedback0http://www.shnenglu.com/izualzhy/comments/commentRss/160123.htmlhttp://www.shnenglu.com/izualzhy/services/trackbacks/160123.htmlpthread多线E学习笔记六U程属性篇

其实U程属性我看明白的很少Q因为属性很多,很多都永不到Q很多虽然看了却没法试验下,因此不知道对错。感觉关于多U程有句话说的很对,有很多多U程的程序,只有在多个机器,多个pȝ上都试验q,才知道对不对Q错在哪里?

?usr/include/pthread.h里可以看C堆关于set or get attr的函敎ͼ大概全是q个样子的:pthread_attr_set*() 或者pthread_attr_get*();

想了下,先从一个普通例子开始说P

#include <stdio.h>

#include <unistd.h>

int main()

{

const size_t asize = (8192*1024+1024*1024*2)/sizeof(int);

/*const size_t asize = 8388608/sizeof(int);*/

printf("heap:\n");

int *parray;

parray = malloc(asize*sizeof(int));

parray[asize-1] = 1;

printf("stack:\n");

int array[asize];

printf("%u\n",asize);

array[asize-1]=1;

return 0;

}


E序输出Q?

heap:

stack:

D错?

Z么会q样?因ؓ每个q程的栈大小是有限制的,例如我的Q?

$ ulimit -a

core file size (blocks, -c) 0

data seg size (kbytes, -d) unlimited

scheduling priority (-e) 20

file size (blocks, -f) unlimited

pending signals (-i) 16382

max locked memory (kbytes, -l) 64

max memory size (kbytes, -m) unlimited

open files (-n) 1024

pipe size (512 bytes, -p) 8

POSIX message queues (bytes, -q) 819200

real-time priority (-r) 0

stack size (kbytes, -s) 8192

cpu time (seconds, -t) unlimited

max user processes (-u) unlimited

virtual memory (kbytes, -v) unlimited

file locks (-x) unlimited

通过ulimit –s可以修改q程栈的大小使这个程序运行OKQ也可能不行Q跟g有关Q?

我们q里数组大小不止用到?192kQ因为linux下还有一个栈的缓冲区?

实际上进E在q行时ƈ不一定会用到8192k大小的栈Q这是一个最大|可以写两个用不同栈大小的例子,pause后,查看/proc/*/maps试验下?

但线E是不同的,U程的栈可以通过暴露栈指针的方式׃n。无论线E用多的栈,q程都会分配一定数目(我的?MQ可以通过U程属性函数来查看Q大的栈给U程使用。如果线E不是以detachl束的,那么只有用join函数获得U程退出状态后才能回收该线E资源,q就是最开始我们说到join函数的作用?

用一个例子测试下U程数目Q?/p>

#include <stdio.h>

#include <string.h>

#include <pthread.h>

void *test(void *arg)

{

/*pthread_detach(pthread_self());*/

}

int main()

{

int err;

int i = 0;

pthread_t tid;

pthread_attr_t attr;

pthread_attr_init(&attr);

pthread_attr_setstacksize(&attr,1024*1024*16);

while (1) {

err = pthread_create(&tid,NULL,test,NULL);

/*err = pthread_create(&tid,&attr,test,NULL);*/

if (err!=0) {

printf("create thread error: %s!\n",strerror(err));

exit(1);

}

++i;

printf("i=%d\n",i);

}

return 0;

}


我的机器上结果是381Q有?82Q注意此时这里返回值就是最开始提到的EAGAIN。如果注释放开的话Q就可以一直运行下去,因ؓ资源被回收。不q用有的机器试验Ӟ数量虽然增大了,但ƈ不能一直运行下厅R没x楚什么原因?

E序里有几个关于属性的函数Q不q暂时没有用刎ͼ关于函数的作用,在pthread.h里可以直接看到?

从网上搜到的关于U程最大数目的解释Q?

q个值和理论完全相符Q因?32 ?linux 下的q程用户I间?3G 的大,也就?3072MQ用 3072M 除以 8M ?384Q但是实际上代码D和数据D늭q要占用一些空_q个值应该向下取整到 383Q再减去ȝE,得到 382?

那ؓ什?linuxthreads 上还要少一个线E呢Q这可太对了Q因?linuxthreads q需要一个管理线E?

ZH破内存的限Ӟ可以有两U方?

1) ?ulimit -s 1024 减小默认的栈大小

2) 调用 pthread_create 的时候用 pthread_attr_getstacksize 讄一个较的栈大?

要注意的是,即ɘq样的也无法H破 1024 个线E的限Ӟ除非重新~译 C 库?

虽然l果不是定的,不过q个解释感觉也还是很合理的?

可以通过E序里线E的attrQ即在create的时候不采用NULL而采用这个attrQ徏立线E观察下U程最大数目再计算下验证下l果?

关于最开始那个程序的D错误,在线E里一样会有,相应的通过pthread_attr_setstacksize(&attr,stackSize)可以解决了?

关于属性,很多一知半解的Q就不拿上来ȝ大方了?

关于pthread多线E编E,用的多的话,其实需要学习的地方q有很多Q感觉这些能够满一些基本的使用了,其他的比如信号量{,{再有用上的心得的时候再上来ȝ了?

izualzhy 2011-11-14 22:47 发表评论
]]>
pthread多线E学习笔C条g变量4使用之signal只能唤醒当前处于wait的线E?/title><link>http://www.shnenglu.com/izualzhy/archive/2011/11/14/160122.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Mon, 14 Nov 2011 14:45:00 GMT</pubDate><guid>http://www.shnenglu.com/izualzhy/archive/2011/11/14/160122.html</guid><wfw:comment>http://www.shnenglu.com/izualzhy/comments/160122.html</wfw:comment><comments>http://www.shnenglu.com/izualzhy/archive/2011/11/14/160122.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/izualzhy/comments/commentRss/160122.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/izualzhy/services/trackbacks/160122.html</trackback:ping><description><![CDATA[<p>pthread多线E学习笔C条g变量4使用之signal只能唤醒当前处于wait的线E?<p><strong>直奔主题Q如果signal的时候没有线E在条g{待队列里,那么本次signal没有效果,后箋的线E进入条仉列之后,无法被之前的signal唤醒?/strong> <p>gq与Windows上不一P <p>考虑一个情形,旅客在出URҎ队(q入wait队列Q,当有出租车到来时Q鸣W或者干啥的QM是signalQ,旅客上R?<p>于是有了下面q个例子Q?/p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #cc6633">#include</span> <stdio.h><br><br><span style="color: #cc6633">#include</span> <pthread.h><br><br>pthread_cond_t taxiCond;<br><br>pthread_mutex_t taxiMutex;<br><br><span style="color: #0000ff">void</span> *travelerArrive(<span style="color: #0000ff">void</span> *name)<br><br>{<br><br>printf(<span style="color: #006080">"Traveler: %s need a taxi now!\n"</span>,(<span style="color: #0000ff">char</span>*)name);<br><br>pthread_mutex_lock(&taxiMutex);<br><br>pthread_cond_wait(&taxiCond, &taxiMutex);<br><br>pthread_mutex_unlock(&taxiMutex);<br><br>printf(<span style="color: #006080">"Traveler: %s now got a taxi!\n"</span>,(<span style="color: #0000ff">char</span>*)name);<br><br>pthread_exit((<span style="color: #0000ff">void</span>*)0);<br><br>}<br><br><span style="color: #0000ff">void</span> *taxiArrive(<span style="color: #0000ff">void</span> *name)<br><br>{<br><br>printf(<span style="color: #006080">"Taxi %s arrives\n"</span>,(<span style="color: #0000ff">char</span>*)name);<br><br>pthread_cond_signal(&taxiCond);<br><br>pthread_exit((<span style="color: #0000ff">void</span>*)0);<br><br>}<br><br><span style="color: #0000ff">int</span> main()<br><br>{<br><br>pthread_t thread;<br><br>pthread_attr_t threadAttr;<br><br>pthread_attr_init(&threadAttr);<br><br>pthread_cond_init(&taxiCond,NULL);<br><br><span style="color: #008000">/*pthread_create(&thread, &threadAttr, travelerArrive, (void*)("Liona"));*/</span><br><br><span style="color: #008000">/*sleep(1);*/</span><br><br>pthread_create(&thread, &threadAttr, taxiArrive, (<span style="color: #0000ff">void</span>*)(<span style="color: #006080">"Jack"</span>));<br><br>sleep(1);<br><br>pthread_create(&thread, &threadAttr, travelerArrive, (<span style="color: #0000ff">void</span>*)(<span style="color: #006080">"Susan"</span>));<br><br>sleep(1);<br><br>pthread_create(&thread, &threadAttr, taxiArrive, (<span style="color: #0000ff">void</span>*)(<span style="color: #006080">"Mike"</span>));<br><br>sleep(1);<br><br><span style="color: #0000ff">return</span> 0;<br><br>}<br></pre><br></div> <p>当Jack出租车到辑֐QsignalQ实际上没有效果? <p>当SusanC后,q入wait队列Q是收不到哦啊Jack的signal的? <p>只有当Mike出租车到了后QsignalQSusan收到? <p>E序输出Q? <p>Taxi Jack arrives <p>Traveler: Susan need a taxi now! <p>Taxi Mike arrives <p>Traveler: Susan now got a taxi! <p>如果觉得q样不合理,其实Ҏ改变Q加一个关于旅客h数的全局变量卛_Q修改后的程序如下:</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #cc6633">#include</span> <stdio.h><br><br><span style="color: #cc6633">#include</span> <pthread.h><br><br>pthread_cond_t taxiCond;<br><br>pthread_mutex_t taxiMutex;<br><br><span style="color: #0000ff">int</span> travelerCount = 0;<br><br><span style="color: #0000ff">void</span> *travelerArrive(<span style="color: #0000ff">void</span> *name)<br><br>{<br><br>printf(<span style="color: #006080">"Traveler: %s need a taxi now!\n"</span>,(<span style="color: #0000ff">char</span>*)name);<br><br>pthread_mutex_lock(&taxiMutex);<br><br>travelerCount++;<br><br>pthread_cond_wait(&taxiCond, &taxiMutex);<br><br>travelerCount--;<br><br>pthread_mutex_unlock(&taxiMutex);<br><br>printf(<span style="color: #006080">"Traveler: %s now got a taxi!\n"</span>,(<span style="color: #0000ff">char</span>*)name);<br><br>pthread_exit((<span style="color: #0000ff">void</span>*)0);<br><br>}<br><br><span style="color: #0000ff">void</span> *taxiArrive(<span style="color: #0000ff">void</span> *name)<br><br>{<br><br>printf(<span style="color: #006080">"Taxi %s arrives\n"</span>,(<span style="color: #0000ff">char</span>*)name);<br><br><span style="color: #0000ff">while</span> (1) {<br><br>pthread_mutex_lock(&taxiMutex);<br><br><span style="color: #0000ff">if</span> (travelerCount>0) {<br><br>pthread_cond_signal(&taxiCond);<br><br>pthread_mutex_unlock(&taxiMutex);<br><br><span style="color: #0000ff">break</span>;<br><br>}<br><br>pthread_mutex_unlock(&taxiMutex);<br><br>}<br><br>pthread_exit((<span style="color: #0000ff">void</span>*)0);<br><br>}<br><br><span style="color: #0000ff">int</span> main()<br><br>{<br><br>pthread_t thread;<br><br>pthread_attr_t threadAttr;<br><br>pthread_attr_init(&threadAttr);<br><br>pthread_cond_init(&taxiCond,NULL);<br><br><span style="color: #008000">/*pthread_create(&thread, &threadAttr, travelerArrive, (void*)("Liona"));*/</span><br><br><span style="color: #008000">/*sleep(1);*/</span><br><br>pthread_create(&thread, &threadAttr, taxiArrive, (<span style="color: #0000ff">void</span>*)(<span style="color: #006080">"Jack"</span>));<br><br>sleep(1);<br><br>pthread_create(&thread, &threadAttr, taxiArrive, (<span style="color: #0000ff">void</span>*)(<span style="color: #006080">"Join"</span>));<br><br>sleep(1);<br><br>pthread_create(&thread, &threadAttr, travelerArrive, (<span style="color: #0000ff">void</span>*)(<span style="color: #006080">"Susan"</span>));<br><br>sleep(1);<br><br>pthread_create(&thread, &threadAttr, taxiArrive, (<span style="color: #0000ff">void</span>*)(<span style="color: #006080">"Mike"</span>));<br><br>sleep(1);<br><br>pthread_create(&thread, &threadAttr, travelerArrive, (<span style="color: #0000ff">void</span>*)(<span style="color: #006080">"Lyn"</span>));<br><br>sleep(1);<br><br><span style="color: #0000ff">return</span> 0;<br><br>}<br></pre><br></div><img src ="http://www.shnenglu.com/izualzhy/aggbug/160122.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/izualzhy/" target="_blank">izualzhy</a> 2011-11-14 22:45 <a href="http://www.shnenglu.com/izualzhy/archive/2011/11/14/160122.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pthread多线E学习笔C条g变量3使用之当wait遇到pthread_cancelhttp://www.shnenglu.com/izualzhy/archive/2011/11/14/160121.htmlizualzhyizualzhyMon, 14 Nov 2011 14:44:00 GMThttp://www.shnenglu.com/izualzhy/archive/2011/11/14/160121.htmlhttp://www.shnenglu.com/izualzhy/comments/160121.htmlhttp://www.shnenglu.com/izualzhy/archive/2011/11/14/160121.html#Feedback0http://www.shnenglu.com/izualzhy/comments/commentRss/160121.htmlhttp://www.shnenglu.com/izualzhy/services/trackbacks/160121.htmlpthread多线E学习笔C条g变量3使用之当wait遇到pthread_cancel

pthread_cond_wait,pthread_cond_timewait是被实现为取消点的,取消点的含义是如果该U程是可取消的,那么当到辑֏消点的时候,该线E会取消掉ƈq回?/strong>

先看一个例子:

#include <stdio.h>

#include <pthread.h>

#include <unistd.h>

pthread_mutex_t mutex;

pthread_cond_t cond;

void *child1(void *arg)

{

/*pthread_cleanup_push(pthread_mutex_unlock, &mutex);*/

while (1) {

printf("thread 1 get running\n");

printf("thread 1 pthread_mutex_lock returns %d\n",pthread_mutex_lock(&mutex));

pthread_cond_wait(&cond,&mutex);

printf("thread 1 conditional applied\n");

pthread_mutex_unlock(&mutex);

sleep(5);

}

/*pthread_cleanup_pop(0);//comment 2*/

}

void *child2(void *arg)

{

while (1) {

sleep(3); //comment 3

printf("thread 2 get running.\n");

printf("thread 2 pthread_mutex_lock returns %d\n",pthread_mutex_lock(&mutex));

pthread_cond_wait(&cond,&mutex);

printf("thread 2 conditional applied\n");

pthread_mutex_unlock(&mutex);

sleep(1);

}

}

int main(void)

{

int tid1,tid2;

printf("conditional variable test\n");

pthread_mutex_init(&mutex,NULL);

pthread_cond_init(&cond,NULL);

pthread_create(&tid1, NULL, child1, NULL);

pthread_create(&tid2, NULL, child2, NULL);

do {

sleep(2);//comment 4

pthread_cancel(tid1);//comment 5

sleep(2);//comment 6

pthread_cond_signal(&cond);

}while(1);

sleep(100);

pthread_exit(0);

}

如果注释掉的部分不放开的话Q线E?会一直停在那里,即ȝE不断的去signal?

原因是:

ß pthread_cond_wait ()和pthread_cond_timedwait()都被实现为取消点Q因此,在该处等待的U程立即重新运行,在重新锁定mutex后离开 pthread_cond_wait()Q然后执行取消动作。也是说如果pthread_cond_wait()被取消,mutex是保持锁定状态的Q因而需要定义退出回调函数来为其解锁?

好了Q其实要说明的就是上面这句话?

izualzhy 2011-11-14 22:44 发表评论
]]>
pthread多线E学习笔C条g变量2使用http://www.shnenglu.com/izualzhy/archive/2011/11/14/160120.htmlizualzhyizualzhyMon, 14 Nov 2011 14:41:00 GMThttp://www.shnenglu.com/izualzhy/archive/2011/11/14/160120.htmlhttp://www.shnenglu.com/izualzhy/comments/160120.htmlhttp://www.shnenglu.com/izualzhy/archive/2011/11/14/160120.html#Feedback0http://www.shnenglu.com/izualzhy/comments/commentRss/160120.htmlhttp://www.shnenglu.com/izualzhy/services/trackbacks/160120.htmlpthread多线E学习笔C条g变量2使用

上篇W记的例子运行效果没有问题,但有些疑问还没搞清楚?

wait函数q不是单使该U程q入休眠?/strong>

ß wait函数做以下三步的操作Q?

ß 1.释放Mutex 2.d{待Q不耗费cpu周期Q?3.当被唤醒Ӟ重新锁定互斥锁ƈ重新试条g是否满 ?

ß 需要重新测试条件的原因是因为可能存在多个consumer的情况,卛_果线E不止两个而是多个Q即使线E被唤醒了,如果一个consumer取走了列表里的品,那么另外一个consumer需要重新进入休眠等待。这也是Z么用while不用ifd断的原因。条件变量只是vd和唤醒线E的作用Q具体的判断条gq需用户l出。从wait或者timewait调用成功q回ӞU程需要重新计条Ӟ因ؓ其他的线E可能已l在q行q改变了条g?

wait函数会在 休眠{待之前释放锁,因此producer是不用担心一直获取不到锁的?

传递给wait的互斥量Ҏ件进行保护,调用者把锁住的互斥量传给函数。函数把调用U程攑ֈ{待条g的线E列表上Q然后对互斥量解锁,q两个操作是原子操作。这样就关闭了条件检查和U程q入休眠状态等待条件改变这两个操作之间的时间通道Q这LE就不会错过条g的Q何变化。这是互斥量和条g一起用的原因Q如果consumer判断到列表ؓI,正准备进入休眠,而此时producer产生节点攑ֈ了列表里Qconsumer却接着q入休眠很明显不是我们想要的Q如果producer在其休眠前发Z信号Q又会造成没有接受者的情ŞQ一会会讲到q个Q。waitq回Ӟ互斥量再ơ被锁住?

要注意,一定要在改变条件之后再l线E发信号。否则无意义的唤醒休眠线E就q反我们最初引入条件变量的目的?

关于signal与mutex的相对位|?/b>Q《UNIX高环境~程》里是说都可以的Q只要在cond_signal之后能从列表里取炏V因为是while循环查条Ӟ所以不会存在问题:U程醒来Q发现队列ؓI,然后q回l箋{待。如果代码不能容忍这U竞争,需要在向线E发送信L时候占有互斥量?

关于q个Q从|上找了下资料,也是各执一词,主要是跟当前pȝ环境有关p,因此q无定论。下面的q个感觉是比较合理的Q?

pthread_cond_signal卛_以放在pthread_mutex_lock和pthread_mutex_unlock之间Q也可以攑֜ pthread_mutex_lock和pthread_mutex_unlock之后Q但是各有有~点?

之间Q?

pthread_mutex_lock

xxxxxxx

pthread_cond_signal

pthread_mutex_unlock

~点Q在某下U程的实CQ会造成{待U程从内怸唤醒Q由于cond_signal)然后又回到内核空_因ؓcond_waitq回后会有原子加锁的 行ؓQ,所以一来一回会有性能的问题。但是在LinuxThreads或者NPTL里面Q就不会有这个问题,因ؓ在Linux U程中,有两个队列,分别是cond_wait队列和mutex_lock队列Q?cond_signal只是让线E从cond_wait队列Udmutex_lock队列Q而不用返回到用户I间Q不会有性能的损耗?

所以在Linux中推荐用这U模式?

之后Q?

pthread_mutex_lock

xxxxxxx

pthread_mutex_unlock

pthread_cond_signal

优点Q不会出C前说的那个潜在的性能损耗,因ؓ在signal之前已l释N?

~点Q如果unlock和signal之前Q有个低优先U的U程正在mutex上等待的话,那么q个低优先的线E就会抢占高优先U的U程 Qcond_wait的线E?Q而这在上面的放中间的模式下是不会出现的?

所以,在Linux下最好pthread_cond_signal放中_但从~程规则上说Q其他两U都可以?

我理解ؓsignal后唤醒的U程会具有较高的加锁优先U,如果有多个线E在{待l该互斥量加锁的话,唤醒U程会获取得到锁Q而这在大部分情况下都是我们所希望看到的。当然如文章中所aQ可能会有性能的问题?

关于signal与broadcast的区别,扑ֈ一个解释很有意思(如果我的看明白了的话)Q?

FiLH wrote On 03/29/06 08:47,:

Hello,

I wonder what is the effective usage difference between

pthread_cond_signal and pthread_cond_broadcast.

I understand that the first awake one waiting thread, and the second

all the waiting threads (on that condition),

That is the difference.

but be seen that the

awkaed thread should enter a mutex, it seems to me in the second case

that only one thread will run while the other one will go back

waiting. But than, I see no big differences, so I must miss something,

but.. what ?

All the threads wake up, and all try to lock the

mutex. Only one at a time can succeed, and the others

must wait for a later opportunity. Yes, they "go back

waiting" -- but they are not waiting for the condition

any more, they are waiting to lock the mutex.

The bugler sounds Reveille, all the soldiers in the

barracks awaken, and they all rush for the lone shower

stall. One soldier gets there first and showers, while

the others stand around fidgeting. When the first is

done, there's a brief struggle among the others until

a second soldier hits the shower, and so on until all

the soldiers have made themselves nice and clean and

ready to go crawl in the mud all day. The soldiers who

don't happen to be first into the shower don't all go

back to bed and await another bugle call (they might

wish to, but the Drill Sergeant has other ideas).

ok。可能关于一些问题,更多的还需要具体情况具体分析?/p>

izualzhy 2011-11-14 22:41 发表评论
]]>
pthread多线E学习笔C条g变量1介绍http://www.shnenglu.com/izualzhy/archive/2011/11/14/160119.htmlizualzhyizualzhyMon, 14 Nov 2011 14:40:00 GMThttp://www.shnenglu.com/izualzhy/archive/2011/11/14/160119.htmlhttp://www.shnenglu.com/izualzhy/comments/160119.htmlhttp://www.shnenglu.com/izualzhy/archive/2011/11/14/160119.html#Feedback0http://www.shnenglu.com/izualzhy/comments/commentRss/160119.htmlhttp://www.shnenglu.com/izualzhy/services/trackbacks/160119.htmlpthread多线E学习笔C条g变量1介绍

互斥量是用来上锁的。有时候我们需要这样一U情形:

U程A需要等某个条g成立才能l箋往下执行,现在q个条g不成立,U程A阻塞等待,而线EB在执行过E中使这个条件成立了Q就唤醒Al箋执行?

使用互斥量固然可以,U程A不断的去试加锁Q但却造成cpu周期的浪费,U程A的阻塞等待能是不耗费cpu周期的?

q就是引入条件变量的作用?

ß 条g变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线E,直到某特D情况发生ؓ止。通常条g变量和互斥锁同时使用?

ß 条g变量使我们可以睡眠等待某U条件出现。条件变量是利用U程间共享的全局变量q行同步的一U机Ӟ主要包括两个动作Q一个线E等?条g变量的条件成?而挂P另一个线E"条g成立"Q给出条件成立信P?

针对条g变量的这两个动作Q就定义了条件变量响应的两个函数?

{待Q?

ß int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

ß int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex_t *mutex, const struct timespec *timeout)

W二个函C比第一个多了时间变量,如果l定旉内还未被唤醒Q则q回ETIMEDOUT。注意时间是一个绝对D不是一个相对|具体使用可以先用gettimeofday函数获得旉?

唤醒Q?

ß int pthread_cond_signal(pthread_cond_t *cond)

ß int pthread_cond_broadcast(pthread_cond_t *cond)

POSIXZ化实玎ͼ允许pthread_cond_signal在实现的时候可以唤醒不止一个线E?

条g变量的类型标识符是pthread_cond_t,与互斥量一P需要初始化Q用完后需要销毁?

ß 初始?

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t*attr);

PTHREAD_COND_INITIALIZER

ß 销毁:int pthread_cond_destroy(pthread_cond_t *cond)

看一个例子,有点长,是生产?消费者模型的例子。从一教E里扑ֈ的,量的完善了下,修改了其中可能引起问题的地方?

生者和消费者都是单独的一个线E,生者生产品,消费者从中取Z品,产品是一个队列,生者new一个节Ҏ加进来,消费者取Z个节点ƈfree掉,当消费者取的速度很快Q而生产者生产的很慢Ӟ消费者就q入休眠{等QwaitQ,而当生者生产品后Q就唤醒QsignalQ消费者队列。程序节点定义ؓ一个结构体msg?/p>

#include <stdlib.h>

#include <pthread.h>

#include <stdio.h>

struct msg {

struct msg *next;

int num;

};

volatile struct msg *head;

pthread_cond_t hasProduct = PTHREAD_COND_INITIALIZER;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void *consumer(void *p)

{

struct msg *mp;

for(;;) {

pthread_mutex_lock(&lock);

while (head==NULL) {

/*if (head==NULL) {*/

//条g受互斥锁保护?

//用while不用if?

printf("consumer entering wait......\n");

pthread_cond_wait(&hasProduct,&lock);

printf("consumer leaveing wait : %d......\n",head->num);

}

mp = head;

head = mp->next;

printf("Consume %d\n",mp->num);

pthread_mutex_unlock(&lock);

free(mp);

sleep(rand()%5);

}

}

void *producer(void *p)

{

struct msg *mp;

for(;;) {

mp = malloc(sizeof(struct msg));

mp->num = rand()%1000 + 1;

pthread_mutex_lock(&lock);

mp->next = head;

head = mp;

printf("Produce %d\n",mp->num);

pthread_mutex_unlock(&lock);

pthread_cond_signal(&hasProduct);

//signal与lock位置无关

sleep(rand()%5);

}

}

int main(int argc, char *argv[])

{

pthread_t pid,cid;

srand(time(NULL));

pthread_create(&pid,NULL, producer, NULL);

pthread_create(&cid,NULL, consumer, NULL);

pthread_join(pid,NULL);

pthread_join(cid,NULL);

struct msg* mp = head;

while (head!=NULL) {

mp = head;

head = head->next;

printf("main thread: %d\n",mp->num);

free(mp);

}

return 0;

}

q个例子是多U程~程里比较经典的例子Q刚开始学习条件变量时其实很多问题没弄明白。没关系Q其实很多条件变量的例子形式都差不多是这个样子。关于我的疑问,先提出来Q下笔记里一个一个记录下扑ֈ的和惛_的答案。。?

1. consumer里ؓ什么是while而不是ifQ要知道producer是改变了条g了才signal的?/strong>

2. wait一定要在lock之后Qؓ什么用mutexM护cond?

3. signal的位|和mutex有关?

4. wait函数做了什么,如果只是休眠{待的话。producer会阻塞在lock函数上(consumer先lock了mutexQ?/strong>

izualzhy 2011-11-14 22:40 发表评论
]]>
pthread多线E学习笔记四互斥?使用http://www.shnenglu.com/izualzhy/archive/2011/11/13/160047.htmlizualzhyizualzhySun, 13 Nov 2011 14:58:00 GMThttp://www.shnenglu.com/izualzhy/archive/2011/11/13/160047.htmlhttp://www.shnenglu.com/izualzhy/comments/160047.htmlhttp://www.shnenglu.com/izualzhy/archive/2011/11/13/160047.html#Feedback0http://www.shnenglu.com/izualzhy/comments/commentRss/160047.htmlhttp://www.shnenglu.com/izualzhy/services/trackbacks/160047.htmlpthread多线E学习笔记四互斥?使用

上篇W记介绍了互斥量的基本定义,q篇主要介绍其用方法?

对应其作用,关于互斥量的函数有这么几个:

1. 初始化:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);或者Pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//静态分?

2. 加锁QInt pthread_mutex_lock(pthread_mutex_t* mutex); Int pthread_mutex_trylock(pthread_mutex_t* mutex);

3. 解锁Int pthread_mutex_unlock(pthread_mutex_t* mutex)

4. 销毁:Int pthread_mutex_destroy(pthread_mutex_t *mutex);

具体的用直接看个例子,从《UNIX 环境高~程》上抄的Q?/p>

/*mutex.c*/

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

#include <errno.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int lock_var;

time_t end_time;

void pthread1(void *arg);

void pthread2(void *arg);

int main(int argc, char *argv[])

{

pthread_t id1,id2;

pthread_t mon_th_id;

int ret;

end_time = time(NULL) + 10;

/** 互斥锁初始化*/

pthread_mutex_init(&mutex,NULL);

/** 创徏两个U程*/

ret = pthread_create(&id1,NULL,(void *)pthread1,NULL);

if (ret!=0) {

perror("pthread create error.\n");

exit(-1);

}

ret = pthread_create(&id2,NULL,(void *)pthread2,NULL);

if (ret!=0) {

perror("pthread create error.\n");

}

pthread_join(id1,NULL);

pthread_join(id2,NULL);

pthread_mutex_destroy(&mutex);

exit(0);

}

void pthread1(void *arg)

{

int i;

while (time(NULL) < end_time) {

/** 互斥锁上?/

if (pthread_mutex_lock(&mutex)!=0) {

perror("pthread_mutex_lock");

} else {

printf("pthread1:pthread1 lock the variable %d\n",lock_var);

}

for (i=0; i<2; i++) {

sleep(1);

lock_var++;

}

/** 互斥锁解?/

if (pthread_mutex_unlock(&mutex)!=0) {

perror("pthread_mutex_unlock.");

} else {

printf("pthread1:pthread1 unlock the variable %d\n",lock_var);

}

sleep(1);

}

}

void pthread2(void *arg)

{

int ret;

while (time(NULL) < end_time) {

/** 试互斥?/

ret = pthread_mutex_trylock(&mutex);

if (ret == EBUSY) {

printf("pthread2:the variable is locked by pthread1\n");

} else {

if (ret!=0) {

perror("pthread_mutex_trylock");

exit(1);

} else {

printf("pthread2:pthread2 got lock. The variable is %d\n",lock_var);

}

if (pthread_mutex_unlock(&mutex)!=0) {

perror("pthread_mutex_unlock");

} else {

printf("pthread2:pthread2 unlock the variable\n");

}

}

sleep(3);

}

}


需要说明的有两点:

1. lock函数会阻塞等待,直到获得?

2. trylock函数不会d{待Q如果互斥量当前被锁Q则q回EBUSY倹{?

Ҏ出错的情形:

A

ß pthread_mutex_lock (theMutex);

ß pthread_mutex_lock (theMutex);

ß pthread_mutex_unlock (theMutex);

ß pthread_mutex_unlock (theMutex);

表面上看E序加锁两次Q然后解锁两ơ没有错Q实际上加锁W二ơ的时候就出错了?

BQ?

clip_image002clip_image004

卛_在多个互斥量时的问题Q两个线E都在等在另一个线E解锁才能l往下执行?

到q种情况Q我们一般约定一?-2-3…的加锁序Q所有线E都遵守q一U定才行?

但即使这P有时候应用程序的l构使得对互斥量加锁q行排序是很困难的,如果涉及了太多的锁和数据l构Q可用的函数q不能把它{换成单的层次Q那么就需要采用另外的办法。可以先释放所有的锁,然后q一D|间再试。这U情况可以用pthread_mutex_trylock接口避免死锁?

ß 互斥锁一个明昄~点是它只有两种状态:锁定和非锁定。设想一U简单情景:多个U程讉K同一个共享资源时Qƈ不知道何时应该用共享资源,如果在界区里加入判断语句,或者可以有效,但一来效率不高,二来复杂环境下就难以~写了,q是我们需要一个结构,能在条g成立时触发相应线E,q行变量修改和访问?

针对此问题,下一开始学习条件变量?

izualzhy 2011-11-13 22:58 发表评论
]]>
pthread多线E学习笔记四互斥?介绍http://www.shnenglu.com/izualzhy/archive/2011/11/13/160046.htmlizualzhyizualzhySun, 13 Nov 2011 14:56:00 GMThttp://www.shnenglu.com/izualzhy/archive/2011/11/13/160046.htmlhttp://www.shnenglu.com/izualzhy/comments/160046.htmlhttp://www.shnenglu.com/izualzhy/archive/2011/11/13/160046.html#Feedback0http://www.shnenglu.com/izualzhy/comments/commentRss/160046.htmlhttp://www.shnenglu.com/izualzhy/services/trackbacks/160046.htmlpthread多线E学习笔记四互斥?介绍

多线E资源共享可以说有利有弊Q这点从W记一可以清楚的看刎ͼ子线E修改内存后Q主U程可以看到Q但子线Efree后,ȝE再ơfree有问题了)?

更直接一点的错误Q如果子U程修改那块内存的时候,ȝE同时在修改会发生什么状c答案是Q不定。因此,U程同步变得很重要。解x法就是不允许多个U程同时M改一个变量?

ß 当一个线E修改变量时Q其他线E在dq个变量的值时可能看C一L数倹{?

ß 在变量修Ҏ间多于一个存储器讉K周期的处理器l构中,当存储器M存储器写q两个周期交叉时Q这U潜在的不一致性就会出现?

因此引入了互斥量?

看个例子可能Ҏ理解一些:

void *threadA(void *) { i++; }

void *threadB(void *) { i++; }

对应于自增的操作Q?

clip_image002 clip_image004 clip_image006

从左到右依次为AU程QBU程和我们看到的i的倹{横向的表示同一旉。我们把q种一个时间点上cpu能完成的动作UCؓ原子操作Q那么如果操作不是原子操作时Q不一致性就出现了?

合理的办法是当AU程修改i的时候,BU程应当d{待Q直到AU程修改完毕QBU程再开始修攏V或者Aȝ待B完成?

像是锁QAQBM改i的时候都试去锁住iQ如果i处于没被锁住Q解锁)状态,则可以锁上,若i处于锁住状态,则阻塞等待直到i被别的线E开锁后可以锁住i为止?

我刚开始理解ؓ互斥量就是用来保护一个变量的Q后来发现是错误的?

像如果B试M改i的时候没有先试ȝ互斥量加锁,一样可以修改iQ一样会产生问题。。?

因此互斥量加锁,解锁的位|都是由我们自己来确定的?

我的理解是,互斥量可以锁住一块区域,因此抛开变量来解释,最直观的就是,当线EA执行某段代码Ӟ不希望别的线E同时来修改其要d或者修改的变量Q可能有多个Q,因此对互斥量加锁Q直到这D代码结束,再对其解锁。这样就一定管用吗Q如果线EB执行的某D代码可能会修改U程A所不希望别的线E所修改的那些变量,而线EB又没有先试加锁Q看下有没有U程已锁住互斥量Q若有,则需要阻塞等待)的话Q结果ƈ不确定,互斥量是不会起作用的。因此,q更像是个“君子协定”(从一教E里看到的,q挺贴切。。。。。。)Q如何确保程序正,在哪个线E哪里加锁与解锁都需要写E序的h来保证。互斥量的作用仅仅是加锁与解锁?

真啰嗦。。。不q我实看了几个例子后才明白。。?

使用互斥量先看个例子Q?

单实例模式(在看一本设计模式书的时候看到的Q?/p>

#include <pthread.h>

#include <stdio.h>

#include <unistd.h>

class Test {

public:

static Test* instance() {

if (NULL == m_instance) {

sleep(1);

printf("m_instance is NULL\n");

m_instance = new Test;

}

return m_instance;

}

static Test* m_instance;

void print(char* tip)

{

printf("In: %s,Test print %x\n",tip,m_instance);

printf("tid: %x\n",pthread_self());

}

private:

Test() {}

Test(const Test& ) {}

};

Test* Test::m_instance = NULL;

void *thr_fn(void* arg)

{

Test::instance()->print("thread");

return ((void*)0);

}

int main()

{

int err;

pthread_t tid;

err = pthread_create(&tid, NULL, thr_fn, NULL);

Test::instance()->print("main thread1");

Test::instance()->print("main thread2");

sleep(2);

return 0;

}


l果会生两个实例,昄不是我们惌的?

if (NULL == m_instance) {

sleep(1);

printf("m_instance is NULL\n");

q里当发现m_instance为空后,休眠1sQ然后newZ个新的出来?

当两个线E运行到q里Qsleep(1)是特意加的)。无论哪个线E先调用该函敎ͼȝE开了子U程后,接着调用Q两个的旉不会过1s......Q会发现m_instance的确为空Q于是休?sQ然后new一个新的出来。该U程休眠的时候,后调用的U程同样调用到这里,跟之前的一P发现为空Q休?sQ然后醒来new一个。于是两个线E休眠醒来的时候都会取new一个实例出来。即产生两个单实例的原因。当然可能跟sleepQ?Q有着关系Q但在许多实际项目里Q这U情况很明显是要避免的?

产生的原因其实跟之前i++相同Q判断的和调用ƈ不是一个原子操作?

如果我们试d下互斥量加锁和解锁两个操作的伪代码:

lock:

if (mutex > 0) {//mutex = 1表示I闲

mutex = 0;

return 0;

} else

挂v{待;

goto lock;

unlock:

mutex = 1;

唤醒{待Mutex的线E?

return 0;

可以看到跟这个例子一Pif判断和调用ƈ不是一个原子操作。因此互斥量具体实现是这LQ?

ß Z实现互斥锁操作,大多Cpȝ构都提供了swap或exchange指oQ该指o的作用是把寄存器和内存单元的数据怺换,׃只有一条指令,保证了原子性,即是多处理器^収ͼ讉K内存的ȝ周期也有先后Q一个处理器上的交换指o执行时另一个处理器的交换指令只能等待ȝ周期

实际上上面这句话我几乎没看懂Q不q没关系Q我惌明的q是那句话,互斥量的作用在这里(使之成ؓ了原子操作)Q而对变量的保护需要写代码的hQ遵循所谓的“君子协议”)来完成?

izualzhy 2011-11-13 22:56 发表评论
]]>
pthread多线E学习笔CU程清理处理E序http://www.shnenglu.com/izualzhy/archive/2011/11/13/160045.htmlizualzhyizualzhySun, 13 Nov 2011 14:53:00 GMThttp://www.shnenglu.com/izualzhy/archive/2011/11/13/160045.htmlhttp://www.shnenglu.com/izualzhy/comments/160045.htmlhttp://www.shnenglu.com/izualzhy/archive/2011/11/13/160045.html#Feedback0http://www.shnenglu.com/izualzhy/comments/commentRss/160045.htmlhttp://www.shnenglu.com/izualzhy/services/trackbacks/160045.htmlpthread多线E学习笔CU程清理处理E序

U程可以安排自己退出时(某些情况下的退?的回调函数?

Void pthread_cleanup_push(void (*rtn)(void*),void *arg);

Void pthread_pop(int execute);

q与q程可以用atexit函数安排q程退出时需要调用的函数是类似的。这L函数UCؓU程清理处理E序(thread cleanup handler)?

先看下这两个函数的实玎ͼ

/* Install a cleanup handler: ROUTINE will be called with arguments ARG

when the thread is canceled or calls pthread_exit. ROUTINE will also

be called with arguments ARG when the matching pthread_cleanup_pop

is executed with non-zero EXECUTE argument.

pthread_cleanup_push and pthread_cleanup_pop are macros and must always

be used in matching pairs at the same nesting level of braces. */

# define pthread_cleanup_push(routine, arg) \

do { \

__pthread_cleanup_class __clframe (routine, arg)

/* Remove a cleanup handler installed by the matching pthread_cleanup_push.

If EXECUTE is non-zero, the handler function is called. */

# define pthread_cleanup_pop(execute) \

__clframe.__setdoit (execute); \

} while (0)

我从pthread.h里给照搬q来了,主要是想说明q两个函数实Cؓ宏,要成对用,英文解释里很明确了呵c?

注意Q?

1. U程可以建立多个清理处理E序Q处理程序记录在栈中Q也是说它们的执行序与它们的注册序相反?

  1. 当线E执行以下动作时调用

1调用pthread_exit?

2响应取消h?

3用非零execute参数调用pthread_cleanup_pop时?

可以看到return时ƈ不会调用?

3. 如果execute参数|?Q清理函C被调用。无论哪U情况,pthread_cleanup_pop都将删除上次pthread_cleanup_push调用建立的清理处理程序?

直接看个例子,<UNIX 环境高~程上的>:

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

void cleanup(void *arg)

{

printf("cleanup: %s\n",(char *)arg);

}

void *thr_fn1(void *arg)

{

printf("thread 1 start\n");

pthread_cleanup_push(cleanup, "thread 1 first handler");

pthread_cleanup_push(cleanup, "thread 1 second handler");

printf("thread 1 push complete\n");

if (arg)

return((void *)1);

pthread_cleanup_pop(0);

pthread_cleanup_pop(0);

return((void *)1);

}

void *thr_fn2(void *arg)

{

printf("thread 2 start\n");

pthread_cleanup_push(cleanup, "thread 2 first handler");

pthread_cleanup_push(cleanup, "thread 2 second handler");

printf("thread 2 push complete\n");

if (arg)

pthread_exit((void *)2);

pthread_cleanup_pop(0);

pthread_cleanup_pop(0);

pthread_exit((void *)2);

}

int main(void)

{

int err;

pthread_t tid1,tid2;

void *tret;

err = pthread_create(&tid1, NULL, thr_fn1, (void *)1);

if (err != 0) {

printf("can't create thread 1: %s\n",strerror(err));

exit(-1);

}

err = pthread_create(&tid2, NULL, thr_fn2, (void *)1);

if (err != 0) {

printf("can't create thread 2: %s\n",strerror(err));

exit(-1);

}

err = pthread_join(tid1, &tret);

if (err != 0) {

printf("can't join with thread 1: %s\n",strerror(err));

exit(-1);

}

printf("thread 1 exit code %d\n",(int)tret);

err = pthread_join(tid2, &tret);

if (err != 0) {

printf("can't join with thread 2: %s\n",strerror(err));

exit(-1);

}

printf("thread 2 exit code %d\n",(int)tret);

}


Technorati 标签: ,
izualzhy 2011-11-13 22:53 发表评论
]]>
pthread多线E学习笔CU程l止、取消与获得q回状?/title><link>http://www.shnenglu.com/izualzhy/archive/2011/11/13/160024.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sun, 13 Nov 2011 07:05:00 GMT</pubDate><guid>http://www.shnenglu.com/izualzhy/archive/2011/11/13/160024.html</guid><wfw:comment>http://www.shnenglu.com/izualzhy/comments/160024.html</wfw:comment><comments>http://www.shnenglu.com/izualzhy/archive/2011/11/13/160024.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/izualzhy/comments/commentRss/160024.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/izualzhy/services/trackbacks/160024.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt"><strong>pthread</strong>多线E学习笔CU程l止、取消与获得q回状?/p><br /><br /> <p>上篇W记里可以看到线E函数的开始和l束意味着U程的开始和l止Q那么就有一个问题,同其他普通函CP如何获得U程q回时的状态?</p> <p>如果子线E运行过E中Q主U程需要取消子U程Q该如何做?</p> <p>子线E退出方式有哪些Q?/p><br /> <p>ß 如果需要只l止某个U程而不l止整个q程Q可以有三种ҎQ?/p> <p>1.从线E函数return。这U方法对ȝE不适用Q从main函数return相当于调用exit?如果q程中Q一U程调用了exit,_Exit或者_exit,那么整个q程׃l止?</p> <p>2.一个线E可以调用pthread_cancell止同一q程中的另一个线E?/p> <p>3.U程可以调用pthread_exitl止自己</p><br /> <p>可以用pthread_join{待U程l束q获得其q回|</p> <p>ß int pthread_join(pthread_t thread, void **rval_ptr)</p> <p>q回|成功q回0Q失败返回错误号(ESRCH,EINVAL{?</p> <p>ß 通过pthread_join得到的终止状态是不同的,ȝ如下Q?/p> <p>1.如果threadU程通过returnq回Qrval_ptr所指向的单元里存放的是threadU程函数的返回倹{?/p> <p>2. 如果threadU程被别的线E调用pthread_cancel异常l止掉,rval_ptr所指向的单元里存放的是常数PTHREAD_CANCELED?/p> <p>3.如果threadU程是自p用pthread_exitl止的,rval_ptr所指向的单元存攄是传lpthread_exit的参数?/p> <p>ß 如果对threadU程的终止状态不感兴,可以传NULLlrval_ptr参数?/p> <p>同之前一P每个函数具体的解释就不记录在q里了,很多教程上有Q?usr/include/pthread.h文g里也可以看到单的注解?/p> <p>注意q个函数和进E里的waitpid很像?/p> <p>调用q个函数其实有两个原因:</p> <p>1. 获得U程q回|存在W二个参数里Q指向指针的指针Q?/p> <p>2. 如果不想获得函数退出状态,只是单纯的想{待U程l束Q可以传NULLl它。要说明的是Q一个线E不能被多个U程{待Q否则第一个接收到信号的线E成功返回,其余调用pthread_join的线E则q回错误代码ESRCH?/p> <p>一般情况下Q线E终止后Q其l止状态一直保留到其它U程调用pthread_join获取它的状态ؓ止。因此用q个函数取等待线E结束是必要的,具体pȝ回收的是那部分资源线E属性里可以体现的很明显Q当然肯定就是线E独有的那部分资?#8230;…但是U程也可以被|ؓdetach状态,q样的线E一旦终止就立刻回收它占用的所有资源,而不保留l止状态。不能对一个已l处于detach状态的U程调用pthread_joinQ这L调用返回EINVAL。对一个尚未detach的线E调用pthread_join或pthread_detach都可以把该线E置为detach状态,也就是说Q不能对同一U程调用两次pthread_joinQ或者如果已l对一个线E调用了pthread_detach׃能再调用pthread_join了。有兴趣的同学可以做个试验,看下在对每个U程讄为detach状态前后系l可以开的最大线E数目对比,看下是否U程资源回收是必要的?/p> <p>W二点好像太啰嗦了(学的一知半解。。)Q不q感觉最主要的是也就是说q里。。。?/p><br /><br /> <p>取消U程Q?/p> <p>int pthread_cancel(pthread_t tid);</p> <p>ß U程可以通过调用该函数来h取消同一q程中的其他U程?/p> <p>ß 在默认情况下Qpthread_cancel函数会得由tid标识的线E的行ؓ表现为如同调用了参数为PTHREAD_CANCELED的pthread_exit函数Q但是线E可以选择忽略取消方式或是控制取消方式。注意pthread_cancelq不{待U程l止Q它仅仅提出h?/p> <p>注意Q?/p> <p>1. #define PTHREAD_CANCELED ((void *) -1)Q因此此旉过join获得q回值其实就?1.</p> <p>2. 该函C仅是提出h。具体被取消U程的动作跟其线E属性相兟?/p> <p>例子Q?/p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #cc6633">#include</span> <pthread.h><br /><br /><span style="color: #cc6633">#include</span> <stdio.h><br /><br /><br /><br /><br /><span style="color: #0000ff">void</span> cleanup(<span style="color: #0000ff">void</span> *arg)<br /><br />{<br /><br />printf(<span style="color: #006080">"clean up \n"</span>);<br /><br />}<br /><br /><span style="color: #0000ff">char</span> c = <span style="color: #006080">'a'</span>;<br /><br /><br /><br /><br /><span style="color: #0000ff">void</span> *print(<span style="color: #0000ff">void</span> *arg)<br /><br />{<br /><br /><span style="color: #0000ff">int</span> i;<br /><br />pthread_cleanup_push(cleanup,NULL);<br /><br /><span style="color: #0000ff">for</span> ( i=0; i<10; ++i) {<br /><br />printf(<span style="color: #006080">"%s\n"</span>,(<span style="color: #0000ff">char</span> *)arg);<br /><br />sleep(2);<br /><br />}<br /><br /><br /><br /><br />pthread_exit((<span style="color: #0000ff">void</span> *)c);<br /><br />pthread_cleanup_pop(0);<br /><br /><span style="color: #008000">/*exit(NULL);*/</span><br /><br />}<br /><br /><br /><br /><br /><span style="color: #0000ff">int</span> main()<br /><br />{<br /><br />pthread_t pid;<br /><br />pthread_create(&pid,NULL,print,<span style="color: #006080">"hello world."</span>);<br /><br /><span style="color: #008000">/*pthread_detach(pid);*/</span><br /><br /><span style="color: #0000ff">int</span> i;<br /><br /><span style="color: #0000ff">for</span>( i=0; i<10; i++) {<br /><br />printf(<span style="color: #006080">"I'm main thread\n"</span>);<br /><br />sleep(1);<br /><br />}<br /><br /><span style="color: #0000ff">void</span> *ret;<br /><br /><span style="color: #008000">/*pthread_cancel(pid);*/</span><br /><br /><span style="color: #0000ff">int</span> r = pthread_join(pid,&ret);<br /><br /><span style="color: #0000ff">if</span> (r != 0) {<br /><br />printf(<span style="color: #006080">"join error: %s\n"</span>,strerror(r));<br /><br />}<br /><br /><span style="color: #008000">/*r = pthread_join(pid,&ret);*/</span><br /><br /><span style="color: #008000">/*if (r != 0) {*/</span><br /><br /><span style="color: #008000">/*printf("join error: %s\n",strerror(r));*/</span><br /><br /><span style="color: #008000">/*}*/</span><br /><br />printf(<span style="color: #006080">"%d\n"</span>,(<span style="color: #0000ff">int</span>*)ret);<br /><br /><br /><br /><br /><span style="color: #0000ff">return</span> 0;<br /><br />}<br /><br /></pre></div> <p>q个例子里注释掉的部分是我用来测试这笔记里大部分感觉要注意的地方的</p><img src ="http://www.shnenglu.com/izualzhy/aggbug/160024.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/izualzhy/" target="_blank">izualzhy</a> 2011-11-13 15:05 <a href="http://www.shnenglu.com/izualzhy/archive/2011/11/13/160024.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pthread多线E学习笔CU程创徏?/title><link>http://www.shnenglu.com/izualzhy/archive/2011/11/13/160022.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sun, 13 Nov 2011 06:59:00 GMT</pubDate><guid>http://www.shnenglu.com/izualzhy/archive/2011/11/13/160022.html</guid><wfw:comment>http://www.shnenglu.com/izualzhy/comments/160022.html</wfw:comment><comments>http://www.shnenglu.com/izualzhy/archive/2011/11/13/160022.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/izualzhy/comments/commentRss/160022.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/izualzhy/services/trackbacks/160022.html</trackback:ping><description><![CDATA[<p align="left"><span style="font-family: 'Calibri','sans-serif'; font-size: 1pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US"><w:sdtPr></w:sdtPr><w:Sdt id="89512082" title="文章标题" storeitemid="X_BC6F93BF-22BA-4949-BB97-A5EE037A3898" text="t" docpart="C25491BD112C4FE9897CCA633A925D19" xpath="/ns0:BlogPostInfo/ns0:PostTitle"></span><font face="宋体"> </font> </p> <p style="margin: 0cm 0cm 0pt" class="Publishwithline"><strong><font size="5"><font color="#17365d"><span lang="EN-US">pthread</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: major-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: major-latin">多线E学习笔CU程创徏?/span><span lang="EN-US"><w:sdtPr></w:sdtPr></span></font></font></strong></p> <p align="left"></w:Sdt> </p> <div style="border-bottom: #4f81bd 1pt solid; border-left: medium none; padding-bottom: 2pt; padding-left: 0cm; padding-right: 0cm; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-themecolor: accent1; mso-element: para-border-div"> <p style="margin: 2pt 0cm 0pt" class="underline"><span lang="EN-US"><o:p><font size="1"> </font></o:p></span></p></div> <p style="margin: 0cm 0cm 6pt" class="PadderBetweenControlandBody"><span lang="EN-US"><o:p><font size="1"> </font></o:p></span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">最q在学习</span><span lang="EN-US">Linux</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">多线E编E部分,W记之一Q?/span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">U程库函数是?/span><span lang="EN-US">POSIX</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">标准定义的,UCؓ</span><span lang="EN-US">POSIX thread</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">或?/span><span lang="EN-US">pthread</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">。在</span><span lang="EN-US">Linux</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">上线E函C?/span><span lang="EN-US">libpthread</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">׃n库中Q因此在~译时要加上</span><span lang="EN-US">-lpthread</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">选项?/span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">与进E相比:</span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">每个q程都拥有自q数据Dc代码段和堆栈段</span><span lang="EN-US">,</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">q就造成了进E在q行切换{操作时都需要有比较负责的上下文切换{动作。运行于一个进E中的多个线E,它们彼此之间使用相同的地址I间Q共享大部分数据Q启动一个线E所p的空间远q小于启动一个进E所p的空_而且Q线E间彼此切换所需的时间也q远于q程间切换所需要的旉?/span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">先看一个简单的多线E的例子Q?/span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">注意该例子会引v</span><span lang="EN-US">double free</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的问题,是ؓ了说明下U程׃n堆的性质?/span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span lang="EN-US"></span></p><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin"></p> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><span style="color: #008000">//</span><span style="color: #008000">(gcc –o example example.c –lpthread)</span><span style="color: #008000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" />#include </span><span style="color: #000000"><</span><span style="color: #000000">pthread.h</span><span style="color: #000000">></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" />#include </span><span style="color: #000000"><</span><span style="color: #0000ff">string</span><span style="color: #000000">.h</span><span style="color: #000000">></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" />#include </span><span style="color: #000000"><</span><span style="color: #000000">stdio.h</span><span style="color: #000000">></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" />#include </span><span style="color: #000000"><</span><span style="color: #000000">unistd.h</span><span style="color: #000000">></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /> <br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" />pthread_t ntid;<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /> <br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">void</span><span style="color: #000000">*</span><span style="color: #000000"> thr_fn(</span><span style="color: #0000ff">void</span><span style="color: #000000">*</span><span style="color: #000000"> arg)<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img id="Codehighlighter1_172_446_Open_Image" onclick="this.style.display='none'; Codehighlighter1_172_446_Open_Text.style.display='none'; Codehighlighter1_172_446_Closed_Image.style.display='inline'; Codehighlighter1_172_446_Closed_Text.style.display='inline';" align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_172_446_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_172_446_Closed_Text.style.display='none'; Codehighlighter1_172_446_Open_Image.style.display='inline'; Codehighlighter1_172_446_Open_Text.style.display='inline';" align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_172_446_Closed_Text"><img src="http://www.shnenglu.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_172_446_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         </span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000"> c </span><span style="color: #000000">=</span><span style="color: #000000"> (</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">)arg;<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         memset(c,</span><span style="color: #000000">'</span><span style="color: #000000">a</span><span style="color: #000000">'</span><span style="color: #000000">,</span><span style="color: #000000">9</span><span style="color: #000000">);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         c[</span><span style="color: #000000">9</span><span style="color: #000000">]</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img id="Codehighlighter1_261_291_Open_Image" onclick="this.style.display='none'; Codehighlighter1_261_291_Open_Text.style.display='none'; Codehighlighter1_261_291_Closed_Image.style.display='inline'; Codehighlighter1_261_291_Closed_Text.style.display='inline';" align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_261_291_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_261_291_Closed_Text.style.display='none'; Codehighlighter1_261_291_Open_Image.style.display='inline'; Codehighlighter1_261_291_Open_Text.style.display='inline';" align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ContractedSubBlock.gif">         </span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_261_291_Closed_Text">/**/</span><span id="Codehighlighter1_261_291_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">printf("ntid: %x\n",ntid);</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         printf(</span><span style="color: #000000">"</span><span style="color: #000000">thread,pid: %d, tid: %x, %x:%s\n</span><span style="color: #000000">"</span><span style="color: #000000">,getpid(),pthread_self(),(unsigned </span><span style="color: #0000ff">int</span><span style="color: #000000">)arg,(unsigned </span><span style="color: #0000ff">int</span><span style="color: #000000">)c);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         sleep(</span><span style="color: #000000">2</span><span style="color: #000000">);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         free(c);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" />}</span></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /> <br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">int</span><span style="color: #000000"> main()<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /><br /><img id="Codehighlighter1_464_1002_Open_Image" onclick="this.style.display='none'; Codehighlighter1_464_1002_Open_Text.style.display='none'; Codehighlighter1_464_1002_Closed_Image.style.display='inline'; Codehighlighter1_464_1002_Closed_Text.style.display='inline';" align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_464_1002_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_464_1002_Closed_Text.style.display='none'; Codehighlighter1_464_1002_Open_Image.style.display='inline'; Codehighlighter1_464_1002_Open_Text.style.display='inline';" align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_464_1002_Closed_Text"><img src="http://www.shnenglu.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_464_1002_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         </span><span style="color: #0000ff">int</span><span style="color: #000000"> err;<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         </span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000"> p </span><span style="color: #000000">=</span><span style="color: #000000"> (</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">)malloc(</span><span style="color: #000000">10</span><span style="color: #000000">);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         printf(</span><span style="color: #000000">"</span><span style="color: #000000">main thread,pid: %d, tid: %x, %x\n</span><span style="color: #000000">"</span><span style="color: #000000">,getpid(),pthread_self(),(unsigned </span><span style="color: #0000ff">int</span><span style="color: #000000">)p);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         err </span><span style="color: #000000">=</span><span style="color: #000000"> pthread_create(</span><span style="color: #000000">&</span><span style="color: #000000">ntid, NULL, thr_fn,(</span><span style="color: #0000ff">void</span><span style="color: #000000">*</span><span style="color: #000000">)p);</span><span style="color: #008000">//</span><span style="color: #008000">pthread.h</span><span style="color: #008000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000"><br /><img id="Codehighlighter1_716_796_Open_Image" onclick="this.style.display='none'; Codehighlighter1_716_796_Open_Text.style.display='none'; Codehighlighter1_716_796_Closed_Image.style.display='inline'; Codehighlighter1_716_796_Closed_Text.style.display='inline';" align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_716_796_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_716_796_Closed_Text.style.display='none'; Codehighlighter1_716_796_Open_Image.style.display='inline'; Codehighlighter1_716_796_Open_Text.style.display='inline';" align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ContractedSubBlock.gif">         </span><span style="color: #0000ff">if</span><span style="color: #000000"> (err</span><span style="color: #000000">!=</span><span style="color: #000000">0</span><span style="color: #000000">) </span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_716_796_Closed_Text"><img src="http://www.shnenglu.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_716_796_Open_Text"><span style="color: #000000">{<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />                   printf(</span><span style="color: #000000">"</span><span style="color: #000000">exit\n</span><span style="color: #000000">"</span><span style="color: #000000">);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />                   exit(</span><span style="color: #000000">1</span><span style="color: #000000">);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />         }</span></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         sleep(</span><span style="color: #000000">1</span><span style="color: #000000">);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         printf(</span><span style="color: #000000">"</span><span style="color: #000000">main thread,pid: %d, tid: %x, %x:%s\n</span><span style="color: #000000">"</span><span style="color: #000000">,getpid(),pthread_self(),(unsigned </span><span style="color: #0000ff">int</span><span style="color: #000000">)p,(unsigned </span><span style="color: #0000ff">int</span><span style="color: #000000">)p);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         sleep(</span><span style="color: #000000">10</span><span style="color: #000000">);</span><span style="color: #008000">//</span><span style="color: #008000">{待U程l束</span><span style="color: #008000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         free(p);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" />         exit(</span><span style="color: #000000">0</span><span style="color: #000000">);<br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/InBlock.gif" alt="" /><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" />}</span></span><span style="color: #000000"><br /><img align="top" src="http://www.shnenglu.com/images/OutliningIndicators/None.gif" alt="" /></span></div> <p style="margin: 0cm 0cm 10pt" class="MsoNormal">感觉多线E编E可以和q程函数一h看:</span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">最基本的几个函数是如下几个Q?/span></p> <p style="text-indent: -18pt; margin: 0cm 0cm 10pt 36pt; tab-stops: list 36.0pt; mso-list: l1 level1 lfo1" class="MsoNormal"><span style="font-family: 'Wingdings 2'; mso-fareast-font-family: 'Wingdings 2'; mso-bidi-font-family: 'Wingdings 2'" lang="EN-US"><span style="mso-list: Ignore">ß<span style="font: 7pt 'Times New Roman'">  </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">U程标识</span><span lang="EN-US">: pthread_t pthread_self <span style="mso-tab-count: 1">     </span><span style="mso-spacerun: yes">   </span>pthread_equal</span></p> <p style="text-indent: -18pt; margin: 0cm 0cm 10pt 36pt; tab-stops: list 36.0pt; mso-list: l1 level1 lfo1" class="MsoNormal"><span style="font-family: 'Wingdings 2'; mso-fareast-font-family: 'Wingdings 2'; mso-bidi-font-family: 'Wingdings 2'" lang="EN-US"><span style="mso-list: Ignore">ß<span style="font: 7pt 'Times New Roman'">  </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">U程创徏</span><span lang="EN-US">:pthrea_create</span></p> <p style="text-indent: -18pt; margin: 0cm 0cm 10pt 36pt; tab-stops: list 36.0pt; mso-list: l1 level1 lfo1" class="MsoNormal"><span style="font-family: 'Wingdings 2'; mso-fareast-font-family: 'Wingdings 2'; mso-bidi-font-family: 'Wingdings 2'" lang="EN-US"><span style="mso-list: Ignore">ß<span style="font: 7pt 'Times New Roman'">  </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">U程l止</span><span lang="EN-US">:pthread_exit pthread_join</span></p> <p style="text-indent: -18pt; margin: 0cm 0cm 10pt 36pt; tab-stops: list 36.0pt; mso-list: l1 level1 lfo1" class="MsoNormal"><span style="font-family: 'Wingdings 2'; mso-fareast-font-family: 'Wingdings 2'; mso-bidi-font-family: 'Wingdings 2'" lang="EN-US"><span style="mso-list: Ignore">ß<span style="font: 7pt 'Times New Roman'">  </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">U程取消</span><span lang="EN-US">:pthread_cancel</span></p> <p style="text-indent: -18pt; margin: 0cm 0cm 10pt 36pt; tab-stops: list 36.0pt; mso-list: l1 level1 lfo1" class="MsoNormal"><span style="font-family: 'Wingdings 2'; mso-fareast-font-family: 'Wingdings 2'; mso-bidi-font-family: 'Wingdings 2'" lang="EN-US"><span style="mso-list: Ignore">ß<span style="font: 7pt 'Times New Roman'">  </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">U程清理</span><span lang="EN-US">:pthread_cleanup_push pthread_cleanup_pop</span></p> <p style="text-indent: -18pt; margin: 0cm 0cm 10pt 36pt; tab-stops: list 36.0pt; mso-list: l1 level1 lfo1" class="MsoNormal"><span style="font-family: 'Wingdings 2'; mso-fareast-font-family: 'Wingdings 2'; mso-bidi-font-family: 'Wingdings 2'" lang="EN-US"><span style="mso-list: Ignore">ß<span style="font: 7pt 'Times New Roman'">  </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">U程分离属?/span><span lang="EN-US">:pthread_detach </span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">很多书里都会讲到其用法。在</span><span lang="EN-US">/usr/include/pthread.h</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">下也可以直接看到其函数声明和基本的介l?/span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">q里只记录下我学习过E中觉得要注意的几个地方Q?/span></p> <p style="text-indent: -18pt; margin: 0cm 0cm 0pt 18pt; mso-add-space: auto; mso-list: l0 level1 lfo2" class="MsoListParagraphCxSpFirst"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin" lang="EN-US"><span style="mso-list: Ignore">1.<span style="font: 7pt 'Times New Roman'">       </span></span></span><span lang="EN-US">pthread_create</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的参Cl:</span><span lang="EN-US"><br />int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, void *(*start_rtn)(void *),void *arg)</span></p> <p style="margin: 0cm 0cm 0pt 18pt; mso-add-space: auto" class="MsoListParagraphCxSpMiddle"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">一个线E中调用</span><span lang="EN-US">pthread_create()</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">创徏新的U程后,当前U程?/span><span lang="EN-US">pthread_create()</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">q回l箋往下执行,而新的线E所执行的代码由我们传给</span><span lang="EN-US">pthread_create</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的函数指?/span><span lang="EN-US">start_rtn</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">军_?/span><span lang="EN-US">start_rtn</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">函数接收一个参敎ͼ是通过</span><span lang="EN-US">pthread_create</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">?/span><span lang="EN-US">arg</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">参数传递给它的Q该参数的类型ؓ</span><span lang="EN-US">void *</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">Q这个指针按什么类型解释由调用者自己定义?/span><span lang="EN-US">start_routine</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的返回值类型也?/span><span lang="EN-US">void *</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">Q这个指针的含义同样p用者自己定义?/span><span lang="EN-US">start_routine</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">q回Ӟq个U程退Z</span> <span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">?/span></p> <p style="margin: 0cm 0cm 0pt 18pt; mso-add-space: auto" class="MsoListParagraphCxSpMiddle"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">注意如果</span><span lang="EN-US">tidp</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">是全局的变量,不要在子U程里用它Q因为可能子U程q行的时候,ȝE还没有来得及给他赋倹{这也是E序里我们打印子U程</span><span lang="EN-US">ID</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">用了</span><span lang="EN-US">pthread_self</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">而没有用</span><span lang="EN-US">ntid</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的原因?/span></p> <p style="text-indent: -18pt; margin: 0cm 0cm 0pt 18pt; mso-add-space: auto; mso-list: l0 level1 lfo2" class="MsoListParagraphCxSpMiddle"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin" lang="EN-US"><span style="mso-list: Ignore">2.<span style="font: 7pt 'Times New Roman'">       </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">如果</span> <span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">函数有返回|注意对返回值的判断Q例?/span><span lang="EN-US">create</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">时可能返?/span><span lang="EN-US">EAGAIN(</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">表示U程数目q多?/span><span lang="EN-US">)</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">Q?/span><span lang="EN-US">EINVAL(</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">表示属性值非?/span><span lang="EN-US">)</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">Q?/span><span lang="EN-US">join</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">时返?/span><span lang="EN-US">ESRCH(</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">表示没有那个U程Q例如已l?/span><span lang="EN-US">join</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">q一ơ了Q线E资源被收回Q这个线E?/span><span lang="EN-US">id</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">也一赯回收Q就会返回这个错?/span><span lang="EN-US">)</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">{等其他。感觉对以后学习U程属性是比较有用的,因ؓ很多错误从线E属性上可以了解原因Q同时加深对U程属性的理解。这些错误都可以通过</span><span lang="EN-US">man errno</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">来查看?/span></p> <p style="text-indent: -18pt; margin: 0cm 0cm 10pt 18pt; mso-add-space: auto; mso-list: l0 level1 lfo2" class="MsoListParagraphCxSpLast"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin" lang="EN-US"><span style="mso-list: Ignore">3.<span style="font: 7pt 'Times New Roman'">       </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">U程</span><span lang="EN-US">id</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的类型是</span><span lang="EN-US">pthread_t</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">Q它只在当前q程中保证是唯一的,在不同的pȝ?/span><span lang="EN-US">pthread_t</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">q个cd有不同的实现Q它可能是一个整数|也可能是个结构体Q地址{。不q查?/span><span lang="EN-US">/usr/include/bits/pthreadtypes.h</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">可以看到我的pȝ</span><span lang="EN-US">(ubuntu 10.04)</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">q里定义?/span><span lang="EN-US">: typedef unsigned long int pthread_t.</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">因此E序里我们直接用</span><span lang="EN-US">%x</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">打印其倹{?/span></p> <p style="margin: 0cm 0cm 10pt" class="MsoNormal"><span lang="EN-US">ok</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">了。接下来在写个关于线E终止,取消以及获得q回状态的例子?/span></p> <p align="left"> </p> <p style="margin: 0cm 0cm 0pt" class="Publishwithline"><strong><span style="font-size: 1.2em"><span style="color: #17365d"><span lang="EN-US"><span style="font-family: Calibri"></span></span></span></span></strong></p><img src ="http://www.shnenglu.com/izualzhy/aggbug/160022.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/izualzhy/" target="_blank">izualzhy</a> 2011-11-13 14:59 <a href="http://www.shnenglu.com/izualzhy/archive/2011/11/13/160022.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.ter2.cn" target="_blank">þٸ۲AVר</a>| <a href="http://www.vtqqv.cn" target="_blank">ձƷþþþӰԺձ</a>| <a href="http://www.yffd.com.cn" target="_blank">޾ƷҾþþþþ</a>| <a href="http://www.cookfood.cn" target="_blank">þ޾Ʒ˳ۺ</a>| <a href="http://www.jj123.com.cn" target="_blank">þ޹˾Ʒɫ</a>| <a href="http://www.68gz.cn" target="_blank">þù鶹91</a>| <a href="http://www.3hiis.cn" target="_blank">˾þô߽ۺվ</a>| <a href="http://www.0x5e.cn" target="_blank">޾Ʒþþþ66</a>| <a href="http://www.enjoa.cn" target="_blank">ɫۺϾþþþ</a>| <a href="http://www.xiewanliang.cn" target="_blank">Ը߳þþþþþþþ</a>| <a href="http://www.ydxxfw.cn" target="_blank">þþƷwwwˬ</a>| <a href="http://www.debtee.cn" target="_blank">þAV</a>| <a href="http://www.jrtz213.cn" target="_blank">þ˽˹Ʒ</a>| <a href="http://www.studenthotel.cn" target="_blank">þùҹAVӰԺ</a>| <a href="http://www.gx177.cn" target="_blank">ɫۺϾþþþþþþ</a>| <a href="http://www.46test.cn" target="_blank">þþþþAŷAV </a>| <a href="http://www.wyj325.cn" target="_blank">޺ݺۺϾþþþ </a>| <a href="http://www.hdtnet.cn" target="_blank">žžþþƷ</a>| <a href="http://www.wenlitown.cn" target="_blank">޾ƷĻþò</a>| <a href="http://www.baolaiqi.com.cn" target="_blank">þùƷһ</a>| <a href="http://www.sevengreen.cn" target="_blank">ľƷþþþþò</a>| <a href="http://www.dtvpartner.com.cn" target="_blank">ƷƵþ</a>| <a href="http://www.baizen.cn" target="_blank">ٸþþþþñŪ߳</a>| <a href="http://www.4060262.cn" target="_blank">þƵᆱƷ99㽶</a>| <a href="http://www.caregps.cn" target="_blank">ƷۺרƬþþ</a>| <a href="http://www.dlygbx.cn" target="_blank">˾þô߽ۺͼƬ</a>| <a href="http://www.fvnnv.cn" target="_blank">þһۺ</a>| <a href="http://www.fimtb.cn" target="_blank">þþƷվ</a>| <a href="http://www.0470gq.cn" target="_blank">Ʒһþþþþþվ</a>| <a href="http://www.awo6.cn" target="_blank">þۺϸþúݺ97ɫ</a>| <a href="http://www.fjprxr.cn" target="_blank">ëƬŷëƬþþ</a>| <a href="http://www.gpuk.cn" target="_blank">ŷ˾þۺ</a>| <a href="http://www.51uhq.cn" target="_blank">99þۺϾƷ</a>| <a href="http://www.hhyskj.com.cn" target="_blank">þþƷAV㽶</a>| <a href="http://www.2218335.cn" target="_blank">ɫ͵͵þһ</a>| <a href="http://www.yizhu888.cn" target="_blank">þˬ˰</a>| <a href="http://www.0769zc.net.cn" target="_blank">޷?Vþò</a>| <a href="http://www.xiazb.cn" target="_blank">ഺþ</a>| <a href="http://www.debtee.cn" target="_blank">þþƷԴվ</a>| <a href="http://www.hvgt.cn" target="_blank">Ʒþþþ</a>| <a href="http://www.4wfgg.cn" target="_blank">޹Ʒһþhs</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>