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

网站开发工具 晴天娃娃中国商标查询网官网

网站开发工具 晴天娃娃,中国商标查询网官网,宿州做网站的有吗,网络文化经营许可证发证机关个人主页 #xff1a; 个人主页 个人专栏 #xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、线程的总结1. 线程的优点2. 线程的缺点3. 线程异常4.线程和进程 二、线程的控制创建线程线程终止线程等待获取返回值 线程分离 总结 前言 本文作为我对于线程的… 个人主页 个人主页 个人专栏 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、线程的总结1. 线程的优点2. 线程的缺点3. 线程异常4.线程和进程 二、线程的控制创建线程线程终止线程等待获取返回值 线程分离 总结 前言 本文作为我对于线程的简单总结线程控制的知识总结 一、线程的总结 1. 线程的优点 创建一个新线程的代价比创建一个新进程小的多与进程之间的切换相比线程之间的切换需要操作系统做的工作要小线程占有的资源要比进程少很多能充分利用多处理器的可并行数量(并行多个执行流在同一时刻拿着不同的CPU继续运算执行代码)在等待慢速I/O操作结束的同时程序可执行其他的计算任务计算密集型应用为了能在多处理器系统上运行将计算分解到多个线程中实现I/O密集型应用(如下载上传)为了提高性能将I/O操作重叠。线程可以同时等待不同的I/O操作 创建线程并不是越多越好进程的执行效率一定随着线程的数量增多效率为正态分布的(线程的切换)。线程的个数最好 CPU的个数 * CPU的核数 2. 线程的缺点 性能损失一个很少被外部事件阻塞的计算密集型线程往往无法与其他线程共享同一个处理器如果计算密集型线程的数量比可用的处理器多那么可能会有较大的性能损失如增加了额外的同步和调度开销而可用的资源不变健壮性(鲁棒性)降低编写多线程需要全面更深入的考虑在一个多线程程序里因时间分配的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的也就是说线程之间是缺乏保护的缺乏访问控制因为线程共享地址空间那一个线程定义的局部变量 or new出的空间其它线程也能使用这就导致一个线程可能会不小心修改另一个线程正在使用的数据导致数据不一致、逻辑错误甚至程序崩溃编程难度提高编写与调试一个多线程程序比单线程程序困难 3. 线程异常 单个线程如果出现除0野指针问题导致线程崩溃进程也会崩溃线程是进程的执行分支线程出异常就类似进程出异常进而触发信号机制终止进程进程终止该进程内的所有线程也全部终止 创建5个线程其中线程thread-4触发除0异常。 #include iostream #include pthread.h #include unistd.h #include string #include functional #include time.h #include vectorusing func_t std::functionvoid(); const int threadnum 5;class ThreadDate { public:ThreadDate(const std::string name, const uint64_t time, func_t f): threadname(name), createtime(time), func(f){}public:std::string threadname;uint64_t createtime;func_t func; };void Print() {std::cout 执行的任务... std::endl; }void *threadRoutine(void *args) {ThreadDate *td static_castThreadDate *(args);while (true){std::cout new thread name: td-threadname create time: td-createtime std::endl;td-func();if(td-threadname thread-4){std::cout td-threadname 触发异常 std::endl;int a 10;a / 0;}sleep(1);} }int main() {std::vectorpthread_t pthreads;for (int i 0; i threadnum; i){char threadname[64];snprintf(threadname, sizeof(threadname), %s-%d, thread, i);pthread_t tid;ThreadDate *td new ThreadDate(threadname, (uint64_t)time(nullptr), Print);pthread_create(tid, nullptr, threadRoutine, (void *)td);pthreads.push_back(tid);sleep(1);}while (true){std::cout main thread std::endl;sleep(1);}return 0; }其中thread-4线程触发异常进程直接终止。 4.线程和进程 进程是资源分配的基本单位线程是调度的基本单位线程共享进程数据但也有自己的一部分独立的数据(线程ID线程的上下文数据独立的栈结构(pthread库维护)errno信号屏蔽字调度优先级进程的多个线程共享同一个地址空间因此地址空间的代码段数据段都是共享的线程还共享进程的文件描述符表每种信号的处理方式(SIG_IGNSIG_DFL自定义的信号处理函数)当前工作目录(cwd)用户id和组id 进程和线程的关系如下 二、线程的控制 创建线程 函数原型 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 功能创建一个新的线程 参数thread返回线程ID attr设置线程属性attr为nullptr表示使用默认属性 start_routine是函数指针为线程启动后要执行的函数 arg传给线程启动函数的参数 返回值成功返回0失败返回错误码 错误检查传统的一些函数成功返回0失败返回-1并且对全局变量errno赋值以指示错误。pthreads函数出错时不会设置全局变量errno而是将错误码通过返回值返回。pthreads也同样提供线程内errno变量以支持其它使用errno的代码。对于pthreads函数的错误建议通过返回值的判定因为读取返回值要比读取线程内的errno变量更方便。 下面我们要创建一个新线程循环打印new thread’主线程循环打印main thread #include iostream #include pthread.h #include unistd.hvoid *threadRoutine(void *args) {while(true){std::cout new thread std::endl;sleep(1);} }int main() {pthread_t tid;pthread_create(tid, nullptr, threadRoutine, nullptr);while(true){std::cout main thread std::endl;sleep(1);}return 0; }编译时会有报错编译器不认识pthread_create这个函数但我们不是加了头文件吗 我们知道linux没有真正的线程只有轻量级进程的概念所以操作系统只会提供轻量级进程创建的系统调用不会直接提供线程创建的接口。linux为了解决这一问题就在软件层创建了pthread原生线程库对用户提供线程控制接口在内部将线程与轻量级进程一一对应。 这样有什么好处标准化和兼容性(pthread编写的多线程应用程序在遵循POSIX标准的各种Unix-like系统上包括Linux都具有很高的可移植性)灵活性pthread库提供了一套丰富的API用于线程的创建、管理、同步和通信。这使得开发者可以根据应用程序的需求灵活地创建和管理线程实现复杂的并发和并行计算任务。 结果如上。 如何给创建的线程传参 如上arg的类型是void*类型表示任意类型的指针。也就是说我们可以穿一个整形字符串结构体对象。如下传递结构体。 #include iostream #include pthread.h #include unistd.h #include string #include functional #include time.husing func_t std::functionvoid();class ThreadDate { public:ThreadDate(const std::string name, const uint64_t time, func_t f):threadname(name), createtime(time), func(f){} public:std::string threadname;uint64_t createtime;func_t func; };void Print() {std::cout 执行的任务... std::endl; }void *threadRoutine(void *args) {ThreadDate * td static_castThreadDate*(args);while(true){std::cout new thread name: td-threadname create time: td-createtime std::endl;td-func();sleep(1);} }int main() {pthread_t tid;ThreadDate * td new ThreadDate(thread-1, (uint64_t)time(nullptr), Print);pthread_create(tid, nullptr, threadRoutine, (void *)td);while(true){std::cout main thread std::endl;sleep(1);}return 0; }那如何一次创建多个线程与创建多个子进程类似。 #include iostream #include pthread.h #include unistd.h #include string #include functional #include time.h #include vectorusing func_t std::functionvoid(); const int threadnum 5;class ThreadDate { public:ThreadDate(const std::string name, const uint64_t time, func_t f): threadname(name), createtime(time), func(f){}public:std::string threadname;uint64_t createtime;func_t func; };void Print() {std::cout 执行的任务... std::endl; }void *threadRoutine(void *args) {ThreadDate *td static_castThreadDate *(args);while (true){std::cout new thread name: td-threadname create time: td-createtime std::endl;td-func();sleep(1);} }int main() {std::vectorpthread_t pthreads;for (int i 0; i threadnum; i){char threadname[64];snprintf(threadname, sizeof(threadname), %s-%d, thread, i);pthread_t tid;ThreadDate *td new ThreadDate(threadname, (uint64_t)time(nullptr), Print);pthread_create(tid, nullptr, threadRoutine, (void *)td);pthreads.push_back(tid);sleep(1);}while (true){std::cout main thread std::endl;sleep(1);}return 0; }下面代码创建线程并通过返回值打印其线程id。 #include iostream #include pthread.h #include string #include unistd.hvoid *threadRoutine(void *args) {std::string name static_castconst char*(args);while(true){std::cout new thread, name: name std::endl;sleep(1);} }int main() {pthread_t tid;pthread_create(tid, nullptr, threadRoutine, (void*)thread-1);while(true){std::cout main thread, sub thread: tid std::endl;sleep(1);}return 0; }很明显创建出来的线程id与LWP并不同那主线程的id值是否也与LWP不同这我们就要了解一个接口pthread_self线程获取自己的id #include iostream #include pthread.h #include string #include unistd.hvoid *threadRoutine(void *args) {std::string name static_castconst char*(args);while(true){std::cout new thread, name: name thread id is pthread_self() std::endl;sleep(1);} }int main() {pthread_t tid;pthread_create(tid, nullptr, threadRoutine, (void*)thread-1);while(true){std::cout main thread id pthread_self() sub thread id tid std::endl;sleep(1);}return 0; }主线程的id与新线程的id明显不是LWP那是什么呢我们以十六进制打印看看。 #include iostream #include pthread.h #include string #include unistd.h// 转换为十六进制 std::string ToHex(pthread_t tid) {char id[64];snprintf(id, sizeof(id), 0x%lx, tid);return id; }void *threadRoutine(void *args) {std::string name static_castconst char*(args);while(true){std::cout new thread, name: name thread id is ToHex(pthread_self()) std::endl;sleep(1);} }int main() {pthread_t tid;pthread_create(tid, nullptr, threadRoutine, (void*)thread-1);while(true){std::cout main thread id ToHex(pthread_self()) std::endl;sleep(1);}return 0; }现在这个线程id是不是很像地址 没错线程id就是地址。 线程终止 如果需要只终止某个线程而不终止整个进程可以有三个方法 从线程函数return。这种方法对主线程不适用从main函数return相当于调用exit函数 #include iostream #include pthread.h #include string #include unistd.h// 转换为十六进制 std::string ToHex(pthread_t tid) {char id[64];snprintf(id, sizeof(id), 0x%lx, tid);return id; }void *threadRoutine(void *args) {std::string name static_castconst char*(args);int cnt 5;while(cnt--){std::cout new thread, name: name thread id is ToHex(pthread_self()) std::endl;sleep(1);}return nullptr; // 线程终止 }int main() {pthread_t tid;pthread_create(tid, nullptr, threadRoutine, (void*)thread-1);while(true){std::cout main thread id ToHex(pthread_self()) std::endl;sleep(1);}return 0; }线程可以调用pthread_exit终止自己 #include iostream #include pthread.h #include string #include unistd.h// 转换为十六进制 std::string ToHex(pthread_t tid) {char id[64];snprintf(id, sizeof(id), 0x%lx, tid);return id; }void *threadRoutine(void *args) {std::string name static_castconst char*(args);int cnt 5;while(cnt--){std::cout new thread, name: name thread id is ToHex(pthread_self()) std::endl;sleep(1);}//return nullptr; // 线程终止pthread_exit(nullptr); }int main() {pthread_t tid;pthread_create(tid, nullptr, threadRoutine, (void*)thread-1);while(true){std::cout main thread id ToHex(pthread_self()) std::endl;sleep(1);}return 0; }一个线程可以调用pthread_cancel终止同一进程中的另一个线程 功能取消一个执行中的线程参数 thread线程id返回值成功返回0失败返回错误码 不能用exit函数来终止线程这会导致这个进程被终止。 #include iostream #include pthread.h #include string #include unistd.h// 转换为十六进制 std::string ToHex(pthread_t tid) {char id[64];snprintf(id, sizeof(id), 0x%lx, tid);return id; }void *threadRoutine(void *args) {std::string name static_castconst char*(args);int cnt 5;while(cnt--){std::cout new thread, name: name thread id is ToHex(pthread_self()) std::endl;sleep(1);}//return nullptr; // 线程终止exit(13); }int main() {pthread_t tid;pthread_create(tid, nullptr, threadRoutine, (void*)thread-1);while(true){std::cout main thread id ToHex(pthread_self()) std::endl;sleep(1);}return 0; }线程等待 获取返回值 我们知道子进程退出时会有僵尸状态需要父进程来等待子进程。那线程也要被等待吗是的线程也要被等待。线程退出没有等待也会导致类似进程的僵尸问题。线程通过等待获取新线程的返回值。 thread线程idretval指向一个指针后者指向返回值返回值等待成功返回0失败返回错误码 调用该函数的线程将以阻塞的方式等待直到id为thread的线程终止。thread线程以不同的方法终止通过pthread_join的终止状态是不同的如果thread线程通过return返回retval所指向的单元存放的是thread线程函数的返回值如果thread线程被别的线程调用pthread_cancel异常终止retval所指向的单元存放的是常数PTHREAD_CANCELED如果thread线程是自己调用pthread_exit终止的retval所指向的单元存放的是传给pthread_exit的参数如果不想获取thread的返回值可以将nullptr传给retval 以从线程return为例。 #include iostream #include pthread.h #include string #include unistd.h// 转换为十六进制 std::string ToHex(pthread_t tid) {char id[64];snprintf(id, sizeof(id), 0x%lx, tid);return id; }void *threadRoutine(void *args) {std::string name static_castconst char *(args);int cnt 5;while (cnt--){std::cout new thread, name: name thread id is ToHex(pthread_self()) std::endl;sleep(1);}return nullptr; // 线程终止 }int main() {pthread_t tid;pthread_create(tid, nullptr, threadRoutine, (void *)thread-1);std::cout main thread id ToHex(pthread_self()) std::endl;int n pthread_join(tid, nullptr);std::cout main thread done , n : n std::endl;return 0; }线程分离 对于一个线程如果主线程要等待它则会阻塞等待导致主线程自己的任务效率低。如果主线程不等待它则可能导致类似僵尸进程的状态使资源泄漏。这时我们就可以将线程分离。 线程可以设置为分离属性一个线程如果被设置为分离属性则该线程在退出之后不需要其它执行流回收该线程资源而是由操作系统进行回收。 默认情况下新创建的线程是joinable的线程退出后需要对其进行pthread_join操作否则无法释放资源从而造成资源泄漏如果不关心线程的返回值join是一种负担我们可以告诉系统当线程退出时自动释放线程资源。joinable和分离是冲突的一个线程不能既是joinable又是分离的。如果等待一个分离的线程函数会立即返回错误错误码通常为EINVAL thread线程id返回值成功返回0失败返回错误码 分离的线程在同一个进程地址空间相互的线程不会相互干扰但是如果分离的线程崩溃进程也会崩溃。 #include iostream #include pthread.h #include string #include unistd.h// 转换为十六进制 std::string ToHex(pthread_t tid) {char id[64];snprintf(id, sizeof(id), 0x%lx, tid);return id; }void *threadRoutine(void *args) {std::string name static_castconst char *(args);int cnt 5;while (cnt--){std::cout new thread, name: name thread id is ToHex(pthread_self()) std::endl;sleep(1);}int a 10;a / 0; // 除0异常return nullptr; // 线程终止 }int main() {pthread_t tid;pthread_create(tid, nullptr, threadRoutine, (void *)thread-1);std::cout main thread id ToHex(pthread_self()) std::endl;sleep(10);pthread_cancel(tid);// int n pthread_join(tid, nullptr);// std::cout main thread done , n : n std::endl;return 0; }总结 以上就是我对于线程控制的总结。
http://www.hkea.cn/news/14370473/

相关文章:

  • asp网站转php网站建设费用清单
  • 青岛专业网站制作外贸网站如何做推广
  • 网站设计样例响应式 网站 设计软件
  • 浙江网站备案流程海南省建设注册中心网站
  • 江苏网站建设电话中国核工业二三建设有限公司是国企吗
  • 北京专业企业营销网站建设为企业做网站策划案
  • wordpress改字号百度竞价优化
  • 企业网站轮播图邢台市行政区划图
  • 影响网站排名重要因素武功做网站
  • 徐州网站建设公司株洲在线论坛二手市场
  • 单位建设网站注意点长城集团建设有限公司网站
  • 网站制作_做网站_耐思智慧网站备案注销原因
  • 品牌网站如何做seoshopxo开源商城
  • 金华网站建设工程网站建设云定制网站
  • 如何在ftp给网站做百度自动推送网站验证码文件
  • 好网站建设公司选择哪家好做黑彩网站
  • 网站短信接口怎么做企业网站建设与网络营销的关系
  • 国外有哪些网站广西城乡与住房建设厅网站
  • 网站域名注销公司加盟代理
  • 乐云seo网站建设公司上海十大展厅设计公司
  • 免费收录网站推广南联网站建设推广
  • 深圳网站制作公司电话WordPress写的文章无法显示
  • 湖南火电建设有限公司招标网站陈铭生我来找你了
  • 大连做网站一般给多大空间wordpress微信h5登录
  • seo同行网站网页设计方案
  • 全国建筑人才求职招聘网站宁波网站建设推广报价
  • kocool网站开发成都商城网站建设地址
  • 手机网站报价单模板创建微信公众号平台
  • 企业网站管理系统软件有什么好的网站推荐一下
  • 摄影看图网站网站优化百度