连云港网站建设,建设一个企业网站要多少钱,织梦cms怎么安装,泉州全网营销推广一、线程控制 1、线程#xff1a;线程是资源调度的基本单位#xff0c;线程是进程内部的一个执行流#xff0c;在进程的地址空间内运行。在Linux 下没有真正意义上的线程#xff0c;线程是用进程模拟的#xff0c;又被称为轻量级进程。 2、由于同⼀一进程的多个线程共享同…一、线程控制 1、线程线程是资源调度的基本单位线程是进程内部的一个执行流在进程的地址空间内运行。在Linux 下没有真正意义上的线程线程是用进程模拟的又被称为轻量级进程。 2、由于同⼀一进程的多个线程共享同⼀一地址空间。因此Text Segment、Data Segment都是共享的除此之外各线程还共享以下进程资源和环境 1. ⽂文件描述符表 2. 每种信号的处理⽅方式(SIG_IGN、SIG_DFL或者⾃自定义的信号处理函数) 3. 当前⼯工作⽬目录 4. ⽤用户id和组id 但有些资源是每个线程各有一份的 1).线程id 2). 上下⽂文,包括各种寄存器的值、程序计数器和栈指针 3). 栈空间 4). errno变量 5). 信号屏蔽字 6). 调度优先级 3、线程创建 函数原型int pthread_create(pthread_t thread, const pthread_attr_t *attr, void (start_routine) (void ), void *arg); 创建成功返回0 创建失败返回错误码可将错误码通过strerror()转换为字符串描述。 参数1线程id地址只在用户区有效。 参数2线程属性一般设置为NULL。 参数3函数指针指向线程函数。 参数4线程函数的参数。 创建结果 3、终⽌止线程如果需要只终⽌止某个线程⽽而不终⽌止整个进程,可以有三种⽅方法: 1. 从线程函数return。这种⽅方法对主线程不适⽤用,从main函数return相当于调⽤用exit。 2. ⼀一个线程可以调⽤用pthread_cancel终⽌止同⼀一进程中的另⼀一个线程⽤用pthread_cancel终⽌止⼀一个线程分同步和异步两种情况。 3. 线程可以调⽤用pthread_exit终⽌止⾃自⼰己。 4、线程等待 返回值:成功返回0,失败返回错误号 调⽤用该函数的线程将挂起等待,直到id为thread的线程终⽌止。thread线程以不同的⽅方法终⽌止,通过pthread_join得到的终⽌止状态是不同的,总结如下: 1. 如果thread线程通过return返回,value_ptr所指向的单元⾥里存放的是thread线程函数的返回值。 2. 如果thread线程被别的线程调⽤用pthread_cancel异常终掉,value_ptr所指向的单元⾥里存放的是常数PTHREAD_CANCELED。 3. 如果thread线程是⾃自⼰己调⽤用pthread_exit终⽌止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。 如果对thread线程的终⽌止状态不感兴趣,可以 传NULL给value_ptr参数 #includestdio.h #includestdlib.h #includepthread.h void* thread1(void* arg) { printf(new thread1\n); return (void*)123; } void* thread2(void* arg) { while(1) { printf(new thread2\n); sleep(1); pthread_exit((void*)456); } } void* thread3(void* arg)//被其他线程cancel { while(1) { printf(new thread3\n); sleep(1); } return NULL; } int main() { pthread_t tid1,tid2,tid3,tid4; void* val NULL; pthread_create(tid1,NULL,thread1,NULL); pthread_create(tid2,NULL,thread2,NULL); pthread_create(tid3,NULL,thread3,NULL); pthread_create(tid4,NULL,thread4,NULL); pthread_join(tid1,val); printf(thread1 is quit,thread1 id is %lu, exit code:%d\n,tid1,(int)val); pthread_join(tid2,val); printf(thread2 is quit,thread2 id is %lu, exit code:%d\n,tid2,(int)val); pthread_cancel(tid3); pthread_join(tid3,val); printf(thread3 is quit,thread3 id is %lu, exit code:%d\n,tid3,(int)val); return 0; } 运行结果 注 可见在Linux的pthread库中常数PTHREAD_CANCELED的值是-1。可以在头⽂文件pthread.h中找到它的定义。 一般情况下,线程终⽌止后,其终⽌止状态⼀一直保留到其它线程调⽤用pthread_join获取它的状态为止。 但是线程也可以被置为detach 状态,这样的线程⼀一旦终止就⽴立刻回收它占⽤用的所有资源⽽而不保留终⽌止状态。不能对⼀一个已经处于detach状态的线程调⽤用pthread_join,这样的调⽤用将返回EINVAL。 对⼀一个尚未detach的线程调⽤用pthread_join或pthread_detach都可以把该线程置为detach状态,也 就是说,不能对同⼀一线程调⽤用两次pthread_join,或者如果已经对⼀一个线程调用 了pthread_detach就不能再调⽤用pthread_join了 二、分离线程 在任何⼀一个时间点上线程是可结合的joinable或者是分离的detached。一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前 它的存储器资源例如栈是不释放的。相反⼀一个分离的线程是不能被其他线程回收或杀死的它的存储器 资源在它终⽌止时由系统⾃自动释放。 1、默认情况下线程被创建成可结合的。为了避免存储器泄漏每个可结合线程都应该要么被显⽰示地回收即调⽤用pthread_join要么通过调⽤用pthread_detach 函数被分离。如果⼀一个可结合线程结束运⾏行但没有被join则它的状态类似于进程中的Zombie Process即还有⼀一部分资源没有被回收所以创建线程者应该调用 pthread_join来等待线程运⾏行结束并可得到线程的退出代码回收其资源。 2、 由于调⽤用pthread_join后如果该线程没有运⾏行结束调⽤用者会被阻塞在有些情况下我们并不希望如此。例如在Web服务器中当主线程为每个新来的连接 请求创建⼀一个⼦子线程进⾏行处理的时候主线程并不希望因为调⽤用pthread_join⽽而阻塞因为还要继续处理之后到来的连接请求这时可以在⼦子线程中加入 代码 pthread_detach(pthread_self()) 或者⽗父线程调⽤用pthread_detach(thread_id)⾮非阻塞可⽴立即返回 这将该⼦子线程的状态设置为分离的detached如此一来该线程运⾏行结束后会⾃自动释放所有资源。 #includestdio.h #includestdlib.h #includepthread.h void* thread(void *_arg) { //pthread_detach(pthread_self());//线程自已设置自已的可分离属性 printf(new thread is run...\n); return (void*)1; } int main() { pthread_t tid; int ret pthread_create(tid,NULL,thread,NULL); if(ret ! 0) { printf(thread create failed,error code:%s\n,strerror(ret)); return ret; } sleep(1); pthread_detach(tid);//将子线程属性设置为分离非阻塞可立即返回 void* val NULL; if((pthread_join(tid, val) ! 0)) { printf(thread wait failed\n); ret 1; } else { printf(thread id : %u ,exit code : %d\n,tid, (int)val); ret 0; } return ret; } 运行结果