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

试论述外贸网站建设应注意的问题o2o网站源码app

试论述外贸网站建设应注意的问题,o2o网站源码app,idc网站模板,中国菲律宾世预赛直播2. Linux 线程控制 首先#xff0c;**内核中有没有很明确的线程的概念**#xff0c;而有**轻量级进程的概念**。当我们想写多线程代码时#xff0c;可以使用**POSIX线程库**#xff0c;这是一个 处于应用层位置的库#xff0c;几乎所有的Linux发行版都默认带这个库#x…2. Linux 线程控制 首先**内核中有没有很明确的线程的概念**而有**轻量级进程的概念**。当我们想写多线程代码时可以使用**POSIX线程库**这是一个 处于应用层位置的库几乎所有的Linux发行版都默认带这个库使用时需要引入头文件pthread.h2.1 创建线程 2.1.1 基础创建 功能创建一个新的线程 原型 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); 参数 thread:输出型参数返回线程ID attr:设置线程的属性attr为NULL表示使用默认属性 start_routine:是个函数地址线程启动后要执行的函数 arg:传给线程启动函数的参数 返回值成功返回0失败返回错误码传统的一些函数是成功返回0失败返回-1并且对全局变量errno赋值以指示错误pthreads函数出错时不会设置全局变量errno而大部分其他POSIX函数会这样做。而是将错误代码通过返回值返回pthreads同样也提供了线程内的errno变量以支持其它使用errno的代码。对于pthreads函数的错误建议通过返回值来判定因为读取返回值要比读取线程内的errno变量的开销更小 由于是第三方库所以编译时要加上-lpthread myThread : myThread.ccg -o $ $^ -stdc11 -lpthread.PHONY : clean clean:rm -f myThread可以看到这不同的线程拥有同一个进程的pid 当我们想观察线程状态时可以使用ps -aL命令,LWP的时ligtht weight process的缩写PID等于LWP的线程是主线程。当我们使用kill -9命令时杀掉任意一个线程整个进程都会被kill掉 下面这个可以持续观察线程状态 while :; do ps -aL | head -1 ps -aL | grep myThread | grep -v ps; echo ##############################################; sleep 1; done2.1.2 让一个函数被重入让多个执行流同时调用 // 可以被多个执行流执行 void Show(const string s) {cout s say: hello! endl; }void* ThreadRoutine(void* args) {while(true) {// cout new thread, pid is getpid() endl;Show([new thread]);sleep(1); } }int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, nullptr);while(true) {// cout main thread, pid is getpid() endl;Show([main thread]);sleep(1); }return 0; }虽然打印出现了错行的情况但不影响现象的产生 2.1.3 线程之间进行通信很容易 int g_val 0;void* ThreadRoutine(void* args) {while(true) {// cout new thread, pid is getpid() endl;// Show([new thread]);printf(I am new thread, g_val: %d, g_val: %p\n, g_val, g_val);sleep(1); } }int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, nullptr);while(true) {// cout main thread, pid is getpid() endl;// Show([main thread]);g_val;printf(I am main thread, g_val: %d, g_val: %p\n, g_val, g_val);sleep(1); }return 0; }2.1.4 线程任意一个出现异常进程都会退出 void* ThreadRoutine(void* args) {while(true) {cout new thread, pid is getpid() endl;sleep(5);int *p nullptr;*p 1;} }int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, nullptr);while(true) {cout main thread, pid is getpid() endl;sleep(1); }return 0; }2.1.5 观察类型是pthread_t 的 tid 定义 pthread_t 类型是 无符号长整型 typedef unsigned long int pthread_t;可以打印查看 int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, nullptr);while(true) {printf(I am main thread, creat new thread tid is %lu\n);sleep(1); }return 0; }可以看到打印出来的tid的值与LWP的值完全不一样这是因为tid是给用户使用的的而LWP是给OS使用的。 实际上tid充当的是地址在2.4中会介绍 2.1.6 给子线程传递参数 void* ThreadRoutine(void* args) {const char* name (const char*)args;while(true) {printf(%s is running\n, name);sleep(1); } }int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, (void*)new thread);while(true) {printf(main thread is running\n);sleep(1); }return 0; }2.2 线程等待 2.2.1 为什么需要线程等待 已经退出的线程其空间没有被释放仍然在进程的地址空间内。创建新的线程不会复用刚才退出线程的地址空间。如果需要可以获取子线程的返回值 2.2.2 基础使用 功能等待线程结束 原型 int pthread_join(pthread_t thread, void **value_ptr); 参数 thread:线程ID value_ptr:它指向一个指针后者指向线程的返回值 返回值成功返回0失败返回错误码如果thread线程通过return返回,value_ ptr所指向的单元里存放的是thread线程函数的返回值。如果thread线程被别的线程调用pthread_ cancel异常终掉,value_ ptr所指向的单元里存放的是常数PTHREAD_ CANCELED其值为-1。如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。如果对thread线程的终止状态不感兴趣,可以传NULL给value_ ptr参数。 void* ThreadRoutine(void* args) {const char* name (const char*)args;int cnt 5;while(cnt--) {printf(%s is running\n, name);sleep(1); }return nullptr; // 线程走到这里后会默认退出 }int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, (void*)new thread);pthread_join(tid, nullptr); // 主线程等待的时候默认是阻塞等待cout main thread quit endl;return 0; }2.2.3 获取子线程的返回值 void* ThreadRoutine(void* args) {const char* name (const char*)args;int cnt 5;while(cnt--) {printf(%s is running\n, name);sleep(1); }return (void*)1; // 线程走到这里后会默认退出 }int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, (void*)new thread);void* ret;pthread_join(tid, ret); // 主线程等待的时候默认是阻塞等待printf(main thread quit, ret: %d\n, (long long)ret); // 由于void* 是8字节所以这里要用8字节的long long 来进行强转return 0; }如果想要多返回些信息可以使用类 struct Request {Request(int s, int e, string n) : _start(s), _end(e), _name(n) {}// 累加 [start, end]int Run(){int tmp 0;for(int i _start; i_end; i) {tmp i;}return tmp;}int _start;int _end;string _name; };struct Response {Response(int r, int e) : _res(r), _exitCode(e) {}int _res;int _exitCode; };void* GetSum(void* args) {Request* rq static_castRequest*(args);Response* rs new Response(0, 0);// 计算rs-_res rq-Run();delete rq;return rs; }int main() {pthread_t tid;Request* rq new Request(1, 100, new Thread);pthread_create(tid, nullptr, GetSum, rq);void* ret;pthread_join(tid, ret);Response* rs static_castResponse*(ret);printf(res: %d, exitCode: %d\n, rs-_res, rs-_exitCode);delete rs;return 0; }以这个为例子如果一个计算任务很大比如1-100000就可以拆分让不同的线程执行不同的范围最后主线程再将子线程的结果进行汇总 2.3 线程终止 2.3.1 直接使用return 上面的所有例子都是使用这个方法当线程走到return后会默认退出。注意exit()是进程退出函数不是线程当线程函数使用它时会使整个进程退出 2.3.2 pthread_exit 功能线程终止 原型 void pthread_exit(void *value_ptr); 参数 value_ptr:value_ptr不要指向一个局部变量。 返回值无返回值跟进程一样线程结束的时候无法返回到它的调用者自身void* ThreadRoutine(void* args) {const char* name (const char*)args;int cnt 5;while(cnt--) {printf(%s is running\n, name);sleep(1); }pthread_exit((void*) 123); }int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, (void*)new thread);void* ret;pthread_join(tid, ret); // 主线程等待的时候默认是阻塞等待printf(main thread quit, ret: %d\n, (long long)ret); // 由于void* 是8字节所以这里要用8字节的long long 来进行强转return 0; }2.3.3 pthread_cancel 功能取消一个执行中的线程 原型 int pthread_cancel(pthread_t thread); 参数 thread:线程ID 返回值成功返回0失败返回错误码void* ThreadRoutine(void* args) {const char* name (const char*)args;while(true) {printf(%s is running\n, name);sleep(1); } return nullptr; }int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, (void*)new thread);// 主进程取消掉子进程sleep(1);pthread_cancel(tid);void* ret;pthread_join(tid, ret); // 主线程等待的时候默认是阻塞等待printf(main thread quit, ret: %d\n, (long long)ret); // 由于void* 是8字节所以这里要用8字节的long long 来进行强转return 0; }可以看到ret为-1那是因为PTHREAD_ CANCELED其值为-1。见2.2.2 2.4 线程ID及进程地址空间布局 pthread_ create函数会产生一个线程ID存放在第一个参数指向的地址中。该线程ID和前面说的线程ID不是一回事pid和LWP前面讲的线程ID属于进程调度的范畴。因为线程是轻量级进程是操作系统调度器的最小单位所以需要一个数值来唯一表示该线程pthread_ create函数第一个参数指向一个虚拟内存单元该内存单元的地址即为新创建线程的线程ID属于NPTL线程库的范畴。线程库的后续操作就是根据该线程ID来操作线程的线程库NPTL提供了pthread_ self函数可以获得线程自身的ID 功能pthread_self - 获取调用线程的ID原型pthread_t pthread_self(void); 描述pthread_self()函数返回调用线程的ID。与在创建this的pthread_create(3)调用中的*thread中返回的值线程是一样的。 返回值这个函数总是成功返回调用线程的ID。// 将tid以地址的格式打出来即16进制 string ToHex(pthread_t tid) {char hex[64];snprintf(hex, sizeof(hex), %p, tid);return hex; }void* ThreadRoutine(void* args) {while(true) {// 打印出进程id将它转成16进程// cout thread id: ToHex(pthread_self()) endl;printf(thread id: %s\n, ToHex(pthread_self()).c_str());sleep(1);} }int main() {pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, nullptr);while(true) {printf(child tid: %s\n, ToHex(tid).c_str());sleep(1);}pthread_join(tid, nullptr);return 0; }pthread_t到底是什么类型呢取决于实现。对于Linux目前实现的NPTL实现而言pthread_t类型的线程ID本质就是一个进程地址空间上的一个地址。 可以看到除了主线程所有其他线程的独立栈都在共享区具体来讲是在pthread库中tid指向的用户tcb中这样线程在调度运行的时候就不会互相干扰了。 2.5 其它问题 2.5.1 创建多个线程 #include iostream #include vector #include string #include unistd.h #include pthread.h #define NUM 3 using namespace std;struct ThreadData { ThreadData(string name) : _threadName(name) {}string _threadName; };void* ThreadRoutine(void* args) {ThreadData* td static_castThreadData*(args);int cnt 5;while(cnt--) {printf(%s, tid: %p, pid: %d\n, td-_threadName.c_str(), pthread_self(), getpid());sleep(1);}delete td;return nullptr; }int main() {// 创建多个线程vectorpthread_t tids;for (size_t i 0; i NUM; i) {pthread_t tid;ThreadData* td new ThreadData(Thread- to_string(i1));// 给子线程传递数据堆空间是共享的pthread_create(tid, nullptr, ThreadRoutine, td);tids.push_back(tid);}// 等待线程for(const auto t : tids) {pthread_join(t, nullptr);}return 0; }2.5.2 每一个线程自己独立的栈结构 修改ThreadRoutine()函数 void* ThreadRoutine(void* args) {ThreadData* td static_castThreadData*(args);int cnt 5, x 0;while(cnt--) {printf(%s, tid: %p, pid: %d, x: %d, x: %p\n, td-_threadName.c_str(), pthread_self(), getpid(), x, x);x;sleep(1);}delete td;return nullptr; } 可以看到每一个线程都独享一个x即独立的栈空间。注意这里是独立并不是私有其它线程想访问还是可以的比如主线程想访问Thread-2的x值 int *p nullptr;void* ThreadRoutine(void* args) {ThreadData* td static_castThreadData*(args);int cnt 5, x 0;while(cnt--) {printf(%s, tid: %p, pid: %d, x: %d, x: %p\n, td-_threadName.c_str(), pthread_self(), getpid(), x, x);x;// 获取该线程的xif(td-_threadName Thread-2) p x;sleep(1);}delete td;return nullptr; }int main() {// 创建多个线程vectorpthread_t tids;for (size_t i 0; i NUM; i) {pthread_t tid;ThreadData* td new ThreadData(Thread- to_string(i1));// 给子线程传递数据堆空间是共享的pthread_create(tid, nullptr, ThreadRoutine, td);tids.push_back(tid);}sleep(2);printf(Main Thread get x: %d, x: %p\n, *p, p);// ... }2.5.3 全局变量 默认情况下全局变量被所有线程共享 // 共享资源 int gVal 100;void* ThreadRoutine(void* args) {ThreadData* td static_castThreadData*(args);int cnt 5;while(cnt--) {gVal;printf(%s, tid: %p, pid: %d, gVal: %d, gVal: %p\n, td-_threadName.c_str(), pthread_self(), getpid(), gVal, gVal);sleep(1);}delete td;return nullptr; }如果想要让每个进程独享该变量可以在变量前加上__thread让编译器把该变量放到tcb的线程局部存储单元中见2.4。注意这里只能初始化内置类型自定义类型是不可以的 __thread int gVal 100;介绍一个__thread的用法减少系统调用 __thread unsigned long int self 0; __thread int tPid 0; void* ThreadRoutine(void* args) {ThreadData* td static_castThreadData*(args);self pthread_self();tPid getpid();int cnt 5;while(cnt--) {printf(%s, tid: %p, pid: %d\n, td-_threadName.c_str(), self, tPid);sleep(1);}delete td;return nullptr; }像上面这样就减少了系统调用的次数。可以将这样的变量理解为线程级别的全局变量不同线程之间变量互不干扰。 2.6 分离线程 默认情况下新创建的线程是joinable的线程退出后需要对其进行pthread_join操作否则无法释放资源从而造成系统泄漏。如果不关心线程的返回值join是一种负担这个时候我们可以告诉系统当线程退出时自动释放线程资源。 int pthread_detach(pthread_t thread);可以是线程组内其他线程对目标线程进行分离也可以是线程自己分离: pthread_detach(pthread_self());joinable和分离是冲突的一个线程不能既是joinable又是分离的 __thread unsigned long int self 0; __thread int tPid 0; void* ThreadRoutine(void* args) {ThreadData* td static_castThreadData*(args);self pthread_self();tPid getpid();// 自己分离pthread_detach(self);int cnt 5;while(cnt--) {printf(%s, tid: %p, pid: %d\n, td-_threadName.c_str(), self, tPid);sleep(1);}delete td;return nullptr; }int main() {// 创建多个线程vectorpthread_t tids;for (size_t i 0; i NUM; i) {pthread_t tid;ThreadData* td new ThreadData(Thread- to_string(i1));// 给子线程传递数据堆空间是共享的pthread_create(tid, nullptr, ThreadRoutine, td);tids.push_back(tid);}sleep(2);// 等待线程for(const auto t : tids) {int ret pthread_join(t, nullptr);printf(ret: %d, who: %p, why: %s\n, ret, t, strerror(ret));}return 0; }
文章转载自:
http://www.morning.yrhsg.cn.gov.cn.yrhsg.cn
http://www.morning.mrpqg.cn.gov.cn.mrpqg.cn
http://www.morning.jzxqj.cn.gov.cn.jzxqj.cn
http://www.morning.rxpp.cn.gov.cn.rxpp.cn
http://www.morning.mtbsd.cn.gov.cn.mtbsd.cn
http://www.morning.fqnql.cn.gov.cn.fqnql.cn
http://www.morning.bswxt.cn.gov.cn.bswxt.cn
http://www.morning.drcnf.cn.gov.cn.drcnf.cn
http://www.morning.smqjl.cn.gov.cn.smqjl.cn
http://www.morning.kgmkl.cn.gov.cn.kgmkl.cn
http://www.morning.rnlx.cn.gov.cn.rnlx.cn
http://www.morning.kngqd.cn.gov.cn.kngqd.cn
http://www.morning.ryrpq.cn.gov.cn.ryrpq.cn
http://www.morning.jzykw.cn.gov.cn.jzykw.cn
http://www.morning.rckmz.cn.gov.cn.rckmz.cn
http://www.morning.yfnjk.cn.gov.cn.yfnjk.cn
http://www.morning.clbzy.cn.gov.cn.clbzy.cn
http://www.morning.tsflw.cn.gov.cn.tsflw.cn
http://www.morning.jcwhk.cn.gov.cn.jcwhk.cn
http://www.morning.hmsong.com.gov.cn.hmsong.com
http://www.morning.jjzxn.cn.gov.cn.jjzxn.cn
http://www.morning.tgczj.cn.gov.cn.tgczj.cn
http://www.morning.llthz.cn.gov.cn.llthz.cn
http://www.morning.yuminfo.com.gov.cn.yuminfo.com
http://www.morning.qtryb.cn.gov.cn.qtryb.cn
http://www.morning.bmsqq.cn.gov.cn.bmsqq.cn
http://www.morning.jhrqn.cn.gov.cn.jhrqn.cn
http://www.morning.qjlkp.cn.gov.cn.qjlkp.cn
http://www.morning.bqhlp.cn.gov.cn.bqhlp.cn
http://www.morning.ssgqc.cn.gov.cn.ssgqc.cn
http://www.morning.jjpk.cn.gov.cn.jjpk.cn
http://www.morning.llcsd.cn.gov.cn.llcsd.cn
http://www.morning.qbdsx.cn.gov.cn.qbdsx.cn
http://www.morning.yrck.cn.gov.cn.yrck.cn
http://www.morning.ttryd.cn.gov.cn.ttryd.cn
http://www.morning.xq3nk42mvv.cn.gov.cn.xq3nk42mvv.cn
http://www.morning.dtmjn.cn.gov.cn.dtmjn.cn
http://www.morning.ychoise.com.gov.cn.ychoise.com
http://www.morning.drmbh.cn.gov.cn.drmbh.cn
http://www.morning.ylpl.cn.gov.cn.ylpl.cn
http://www.morning.dqkcn.cn.gov.cn.dqkcn.cn
http://www.morning.rlsd.cn.gov.cn.rlsd.cn
http://www.morning.gqjwz.cn.gov.cn.gqjwz.cn
http://www.morning.yhjrc.cn.gov.cn.yhjrc.cn
http://www.morning.drqrl.cn.gov.cn.drqrl.cn
http://www.morning.gidmag.com.gov.cn.gidmag.com
http://www.morning.wyfpc.cn.gov.cn.wyfpc.cn
http://www.morning.blznh.cn.gov.cn.blznh.cn
http://www.morning.nlywq.cn.gov.cn.nlywq.cn
http://www.morning.ykqbs.cn.gov.cn.ykqbs.cn
http://www.morning.fpczq.cn.gov.cn.fpczq.cn
http://www.morning.dwxqf.cn.gov.cn.dwxqf.cn
http://www.morning.cwjsz.cn.gov.cn.cwjsz.cn
http://www.morning.qbgff.cn.gov.cn.qbgff.cn
http://www.morning.ykxnp.cn.gov.cn.ykxnp.cn
http://www.morning.rqjfm.cn.gov.cn.rqjfm.cn
http://www.morning.gczqt.cn.gov.cn.gczqt.cn
http://www.morning.mehrim.com.gov.cn.mehrim.com
http://www.morning.dnphd.cn.gov.cn.dnphd.cn
http://www.morning.sjsfw.cn.gov.cn.sjsfw.cn
http://www.morning.rkhhl.cn.gov.cn.rkhhl.cn
http://www.morning.dxrbp.cn.gov.cn.dxrbp.cn
http://www.morning.cnprt.cn.gov.cn.cnprt.cn
http://www.morning.zsfooo.com.gov.cn.zsfooo.com
http://www.morning.nbqwr.cn.gov.cn.nbqwr.cn
http://www.morning.xczyj.cn.gov.cn.xczyj.cn
http://www.morning.xlxmy.cn.gov.cn.xlxmy.cn
http://www.morning.rxhs.cn.gov.cn.rxhs.cn
http://www.morning.wjrtg.cn.gov.cn.wjrtg.cn
http://www.morning.rstrc.cn.gov.cn.rstrc.cn
http://www.morning.rzczl.cn.gov.cn.rzczl.cn
http://www.morning.lmknf.cn.gov.cn.lmknf.cn
http://www.morning.dbnpz.cn.gov.cn.dbnpz.cn
http://www.morning.hbnwr.cn.gov.cn.hbnwr.cn
http://www.morning.tlnkz.cn.gov.cn.tlnkz.cn
http://www.morning.ysfj.cn.gov.cn.ysfj.cn
http://www.morning.rdlrm.cn.gov.cn.rdlrm.cn
http://www.morning.sjpht.cn.gov.cn.sjpht.cn
http://www.morning.qlckc.cn.gov.cn.qlckc.cn
http://www.morning.tmxtr.cn.gov.cn.tmxtr.cn
http://www.tj-hxxt.cn/news/236605.html

相关文章:

  • 网站开发用px还是rem有没有免费的分销软件
  • 可以直接进入的正能量网站老狼编写网站
  • 做二手车网站需要什么手续南阳建站公司
  • 怎么给一个花店做网站建设舟山百度seo
  • 北龙中网 可信网站验证 费用技术支持 东莞网站建设母婴护理
  • 网站百度收录idc销售网站模板
  • 温州网站建设咨询做网站经常用的术语
  • 眼镜网站怎么做竞价爱奇艺会员推广联盟
  • 适合个人站长的网站有哪些友妙招链接怎么弄
  • 南充建网站王也道长高清头像 微信
  • 帮别人做网站维护违法建设银行手机官方网站下载安装
  • 杭州做购物网站网站建设yu
  • 网站的收费标准太原seo关键词排名优化
  • 辅助色网站免费模型网站
  • 企业网站源码搜一品资源销售网站排名
  • 网站排名公司哪家好百度域名排行
  • 招聘网站官网wordpress 3.3.1 漏洞
  • 四川建设厅网站怎么进不去电商平台需要什么资质
  • 有没有做废品的网站wordpress自定义注册
  • 手机建站关键词的优化方案
  • 国际互联网网站工商局网站如何做网登
  • 互联网创业项目平台加盟手机端网站如何优化
  • 外贸建站 智能营销什么网站可以做论文
  • php网站系统微网站 合同
  • 厦门公司网站制作流程用齐博cms建网站
  • 莱芜房产网站学生网站做兼职
  • 网站公司排行榜前十名wordpress 插件模板
  • 学校网站 建设网站空间空间租赁
  • 做靓号网站网站建设和优化
  • 东莞营销网站建设公司网页设计分为几个部分