在main函数中调用pthread_exit时,进程不会退出,因此main创建的线程不会退出,但是将释放存储在main局部变量中的堆栈.
#include<cstdio> #include<pthread.h> #include<unistd.h> void* print(void* i) { printf("i got a number %d\n",*(int*)i); sleep(10); printf("i got a number %d\n",*(int*)i); } int main() { pthread_t tid[10]; for(int i=0;i<10;i++) { pthread_create(&tid[i],NULL,print,(void*)&i); } pthread_exit(NULL); }
该程序的子线程的第一个输出与10s之后的输出不同. pthread_exit执行后,将释放局部变量.
功能:
int pthread_join (pthread_t tid, void **thread_return); int pthread_detach (pthread_t tid); int pthread_attr_setdetachstate (pthread_attr_t *attr,int detachstate); int pthread_attr_getdetachstate (const pthread_attr_t *attr,int *detachstate);
连接:
“连接”是一种完成线程之间同步的方法. 例如:
pthread_join()函数阻塞调用线程linux多线程服务器设计,直到tid指定的线程终止.
如果代码中没有pthread_join()函数,则main函数将快速结束,并且整个过程将结束,因此创建的线程将结束,而没有机会开始执行. 添加pthread_join()函数后,主线程将等待,直到等待线程完成,以便创建的线程有机会执行.
如果在目标线程中调用了pthread_exit(),则程序员可以在主线程中获取目标线程的终止状态. 连接线程只能通过pthread_join()连接一次. 如果多次调用,将发生逻辑错误.

还有两种同步方法,互斥和条件变量,将在后面讨论.
线程是可连接的:
创建线程后,它具有定义它是可连接还是可分离的属性. 只有可以连接的线程才能被连接(加入),如果创建的线程被分离,则无法连接.
pthread_create()的attr参数可用于显式创建可连接或可分离的线程. 典型的四个步骤如下:
单独:
pthread_detach()可显式用于分离线程,尽管它们在创建时是可连接的.
创建线程的默认状态是可连接的. 如果线程完成运行但未加入,则其状态类似于进程中的“僵尸进程”,即某些资源尚未回收(退出状态代码),因此创建线程用户应使用pthread_join()等待线程完成运行,并获取线程的退出代码以回收其资源(类似于wait和waitpid). 但是在调用pthread_join()之后,如果线程没有完成运行,则调用者将被阻止,在某些情况下,我们不希望这样做,例如,在Web服务器中,当主线程为每个新链接创建子线程时,进程当时,主线程不想因为调用pthread_join而阻塞(因为它必须继续处理随后出现的链接),然后可以向子线程添加代码
pthread_detach(pthread_self());
或在主线程中调用
pthread_detach(thread_id);//非阻塞,可立即返回
这会将子线程的状态设置为“已分离”,并且程运行完毕后,所有资源将自动释放.
建议:
以下代码演示了pthread_join()的用法
#include <pthread.h> #include <cstdio> #include <unistd.h> void* print1 (void*) { printf("x"); } void* print2 (void*) { printf("y"); } int main () { pthread_t tid1,tid2; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE); pthread_create(&tid1,&attr,&print1,NULL); pthread_create(&tid2,&attr,&print2,NULL); pthread_join(tid1,NULL); pthread_join(tid2,NULL); return 0; }
无法确定输出结果. pthread_join阻止的是调用join函数的主线程. 其目的是等待并确认线程t1和t2的执行结束,但不能保证多个线程的执行顺序. 它仅确定要加入的线程已经结束”,并且与线程执行顺序无关. 它类似于进程的waitpid函数. 可以控制线程执行顺序的是线程的Mutex和Condition Variables.
在创建每个进程之后,应调用pthread_join或pthread_detach函数. 只有这样,线程结束时才可以释放资源(线程描述信息和堆栈). 不在新线程中调用pthread_join或pthread_detach将导致内存泄漏. 如果创建更多线程,则内存利用率将更高. 在不再创建线程之前,只能结束该过程.
有三种解决方案:
#include<pthread.h> #include<cstdio> #include<unistd.h> void* print(void *) { static int g=0; printf("%d\n", g++); pthread_exit(0); } int main() { pthread_t tid; while(1) { pthread_create(&tid,NULL,print,NULL); pthread_detach(tid); } return 0; }
有些内容需要稍后写...
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-241587-2.html
事情没调查清楚你就发布这样误导性的信息
但没有谁备的战争更可怕