网络小说写作网站知名seo网站优化公司

当前位置: 首页 > news >正文

网络小说写作网站,知名seo网站优化公司,陕西省住房和建设厅网站,wordpress采集小说数据线程与多线程#xff08;一#xff09; 一、线程1、概念2、示意图3、虚拟地址转换到物理地址4、与进程相比的优点5、与进程相比的缺点6、与进程的关系#xff08;1#xff09;线程独有#xff08;2#xff09;共享#xff08;3#xff09;示意图 二、POSIX线程库三、创… 线程与多线程一 一、线程1、概念2、示意图3、虚拟地址转换到物理地址4、与进程相比的优点5、与进程相比的缺点6、与进程的关系1线程独有2共享3示意图 二、POSIX线程库三、创建线程1、函数2、概念 四、pthread_self1、函数2、概念3、pthread_t4、示意图5、说明 五、线程终止1、方式2、pthread_exit1函数2概念 3、pthreadcancel1函数2概念 六、线程等待1、函数2、概念3、意义 七、线程库八、示例代码1、代码2、运行结果 九、分离线程1、函数2、概念3、代码4、运行结果 一、线程 1、概念 线程也被称为轻量级进程Lightweight ProcessLWP它是程序执行流的最小单元、操作系统调度的基本单位。用户级执行流与内核LWP间是一一对应的。在整个生命周期中相比于进程线程的创建和释放更加轻量化进程内线程的切换不需要重新cache数据进程内线程的切换运行更加轻量化。在Linux中没有真正义上的线程所谓的线程是用进程内核数据结构模拟的线程。一个线程可以创建和撤消另一个线程同一进程中的多个线程之间可以并发执行。但由于线程之间的相互制约线程在运行中呈现出间断性。在进程的虚拟地址空间中进程拥有大部分资源。将进程的这些资源合理分配给每个执行流就形成了线程执行流。即进程是承担分配系统资源本质为地址空间范围的基本实体线程是进程内部的执行流资源。所以线程是进程内的一个执行分支它执行一部分进程的代码执行粒度要比进程细。每一个程序都至少拥有一个线程即程序本身。而线程是程序中一个单一的顺序控制流程。所以多线程是在单个程序进程中同时运行多个线程完成不同的工作。 2、示意图 3、虚拟地址转换到物理地址 4、与进程相比的优点 创建一个新线程的代价较小。线程之间的切换需要操作系统做的工作较少。占用的资源较少能充分利用多处理器的可并行数量。在等待慢速I/O操作结束的同时程序可执行其他计算任务。在I/O密集型应用中可将I/O操作重叠来提高性能。这样线程就可以同时等待不同的I/O操作。计算密集型应用时可将计算分解到多个线程中以实现在多处理器系统上运行的目的。合理的使用多线程能提高CPU密集型程序的执行效率、IO密集型程序的用户体验。 5、与进程相比的缺点 性能损失一个很少被外部事件阻塞的计算密集型线程往往无法与其它线程共享同一个处理器。健壮性降低在一个多线程程序里因为时间分配上的细微偏差或者因为共享了不该共享的变量而造成不良影响的可能性较大。缺乏访问控制因为进程是访问控制的基本粒度。所以在一个线程中调用某些系统函数会对整个进程造成影响。编程难度高编写与调试一个多线程程序比单线程程序困难。影响较大因为线程是进程的执行分支。所以线程出现异常就类似于进程出现异常。当触发信号机制终止时整个进程都将终止该进程内的所有线程也将退出。即如果一个线程崩溃了这个线程所在的进程内的所有线程都将出错崩溃。 6、与进程的关系 1线程独有 线程ID、一组寄存器、栈空间、errno、信号屏蔽字、调度优先级。 2共享 文件描述符表、每种信号的处理方式SIG IGN、SIG_ DFL或者自定义的信号处理函数、当前工作目录、用户id和组id。 3示意图 二、POSIX线程库 与线程有关的函数构成了一个完整的系列绝大多数函数的名字都是以 pthread_ 开头。当使用POSIX线程库的函数时需要引用头文件pthread.h。当链接POSIX线程库时需要使用编译器命令的 -lpthread 选项。 三、创建线程 1、函数 2、概念 pthread_create函数在调用进程中启动一个新线程该新线程通过调用参数start_routine所指向的函数开始执行参数arg作为start_routine指向的函数的唯一传递的参数。参数attr指向一个pthread_attr_t结构体其内容在线程创建时用于确定新线程的属性。该结构使用pthreadattr_init和相关函数进行初始化。如果attr为NULL则使用默认属性创建线程。在返回之前如果成功调用了pthread_create函数该函数会将新线程的ID存储在线程指向的缓冲区中。此标识符参数thread即线程ID用于在后续调用其他pthread函数时引用对应的线程。新线程继承了调用创建线程函数的线程的信号掩码pthread_sigmask的副本浮点环境fenv。但不继承其备用信号堆栈sigaltstack。新线程挂起信号集sigpending为空CPU时间时钟的初始值为0。 四、pthread_self 1、函数 2、概念 pthread_self函数返回调用此函数的线程的线程ID。这与创建此线程的线程在调用pthread_create函数成功后参数thread返回的值相同。 3、pthread_t 在Linux目前实现的NPTL实现来说pthread_t类型的线程ID本质是一个进程地址空间上的一个地址。 4、示意图 5、说明 在上方的示意图中struct pthread、线程局部存储和线程栈的一整块是线程的tcb即线程控制块。而每一个线程的库级别的tcb的起始地址是线程的tid类型为pthread_t。在进程中除了主线程以外的其他所有线程的独立栈都在共享区中。具体是在pthread库中tid指向的用户tcb中。每一个线程都有自己独立的栈结构线程栈上的数据可以被同一进程内的其他线程看到并访问。如果线程想要一个私有的全局变量可以在全局变量的定义前面加__thread编译选项。这是线程的局部存储只能定义内置类型而不能用来修饰自定义类型。 五、线程终止 1、方式 调用pthread_exit函数指定一个退出状态值该值可供调用pthread_join函数的同一进程中的另一个线程使用。从start_routine指向的函数返回。这相当于使用return语句中提供的值调用pthread_exit函数。被pthread_cancel函数取消。进程中的任何线程调用exit函数或者主线程执行main函数的返回。都会导致进程中所有线程的终止。 2、pthread_exit 1函数 2概念 pthread_exit函数终止调用该函数的线程并通过retval返回一个值该值如果线程是joinable的可供调用pthread_join的同一进程中的另一个线程使用。当线程终止时进程共享资源例如互斥锁、条件变量、信号量和文件描述符不会被释放。在进程中的最后一个线程终止后该进程通过调用退出状态为零的exit来终止进程共享资源将被释放。pthread_exit函数或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的不能在将退出的线程所执行的函数的栈上分配。因为当其它线程得到这个返回指针时该线程已经退出了。此时访问该内存单元的结果是未知的。 3、pthread_cancel 1函数 2概念 pthread_cancel函数向thread线程发送取消请求。目标线程是否以及何时对取消请求做出反应取决于该线程控制的两个属性即其可取消性状态和类型。被取消的线程终止后调用pthread_join等待该线程的线程将获得 PTHREADCANCELED 作为该线程的退出状态。Joining等待一个线程是知道取消操作是否已完成的唯一方法。一个线程可以调用pthread cancel函数终止同一进程中的另一个线程。 六、线程等待 1、函数 2、概念 pthread_join函数等待thread指定的线程终止。如果该线程已经终止则pthread_join函数立即返回否则阻塞等待。thread指定的线程必须是joinable可等待的。如果retval不为NULL则pthread_join函数将目标线程的退出状态即目标线程提供给pthread_exit的值或者执行函数结束时返回的值复制到retval指向的位置。如果目标线程被取消则 PTHREAD_CANCELED 将被放置在retval中。如果多个线程同时尝试等待同一个线程则结果是未定义的。如果调用pthread_join函数的线程被取消那么目标线程将保持joinable状态。即它不会被detached分离。 3、意义 如果不进行等待则已经退出的线程的空间不会被释放仍然在进程的地址空间内有可能造成内存泄漏。如果不进行等待创建新的线程不会复用退出线程的地址空间而当申请线程的数量达到一定值时有可能会内存不足。 七、线程库 内核中没有很明确得线程概念只有轻量级进程的概念。所以Linux操作系统不会直接提供线程相关的系统调用只会提供轻量级进程的系统调用。pthread线程库是在应用层对轻量级进程接口进行封装为用户提供直接线程的接口。几乎所有的Linux平台都默认自带pthread线程库。当在Linux中编写多线程代码时需要使用第三方的pthread库。因为线程库需要维护线程的概念而不用维护线程的执行流。所以库需要对线程进行管理使用时需要加载到内存中即原生线程库是基于内存的。 八、示例代码 1、代码 string ToHex(pthread_t tid) {char buff[64];snprintf(buff, sizeof(buff), %p, tid);return buff; }void *RunRoutine(void *arg) {char threadName (char)arg;for(int i 0; i 5; i){cout threadName , tid: ToHex(pthread_self()) , is running i endl;sleep(1);//pthread_exit((void)1);if(i 2){//exit(1);//return (void)1;}}}int main() {pthread_t tid;pthread_create(tid, nullptr, RunRoutine, (void*)thread 1);cout main thread create work done, new thread id: ToHex(tid) endl;// sleep(1);// pthread_cancel(tid);// cout main thread: getpid() , thread tid ToHex(tid) canceled endl;// sleep(1);int ret pthread_join(tid, nullptr);cout pthread_join wait over, ret ret endl;return 0; } 2、运行结果 放开pthread_exit行注释。 放开exit行注释。 放开return行注释。 放开main内注释。 九、分离线程 1、函数 2、概念 pthread_detach函数可将thread标识的线程标记为已分离但尝试分离已分离的线程的行为是未定义的。当一个分离的线程终止时它的资源会自动释放回系统而不需要另一个线程去等待它。可以是线程组内其他线程对目标线程进行分离也可以是线程自己分离。joinable和分离是冲突的即一个线程不能既是joinable又是分离的。 3、代码 void *RunRoutine(void *arg) {pthread_detach(pthread_self());char threadName (char)arg;for(int i 0; i 5; i){cout threadName , tid: pthread_self() , is running i endl;sleep(1);}}int main() {pthread_t tid;pthread_create(tid, nullptr, RunRoutine, (void*)thread 1);cout main thread create work done, new thread id: tid endl;sleep(6);cout sleep time over endl;return 0; }4、运行结果 本文为线程相关的内容多线程相关的内容参见线程与多线程二。 本文到这里就结束了如有错误或者不清楚的地方欢迎评论或者私信 创作不易如果觉得博主写得不错请点赞、收藏加关注支持一下