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

wordpress制作官方网站百度模拟点击软件判刑了

wordpress制作官方网站,百度模拟点击软件判刑了,网站测试方案,福州哪里做网站目录 ​编辑 POSIX线程库 多线程创建 独立栈结构 获取线程ID pthread_self 线程终止 return终止线程 pthread_exit pthread_cancel 线程等待 退出码问题 线程分离 测试 线程ID及地址空间布局 ​编辑 POSIX线程库 pthread线程库是 POSIX线程库的一部分&#xf…

目录

​编辑

POSIX线程库

 多线程创建

独立栈结构 

获取线程ID 

pthread_self 

 线程终止

return终止线程

pthread_exit

pthread_cancel

线程等待

  退出码问题

 线程分离

测试 

线程ID及地址空间布局 

​编辑


POSIX线程库

pthread线程库是 POSIX线程库的一部分,POSIX线程库也叫原生线程库;

        遵守 POSIX标准:与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”开头的
要使用这些函数库,要通过引入头文<pthread.h>
链接这些线程函数库时要使用编译器命令的 “-lpthread” 选项;

成功返回0,失败返回-1

 多线程创建

主线程创建一批线程;

没有在循环创建中添加sleep();

void* handler(void* arg)
{const char* name = (const char*)arg;while(true){cout<<"new thread sucess name:"<<name<<endl;sleep(1);}
}int main()
{pthread_t tid;char namebuff[64];for(int i = 0;i<5;i++)  {//格式化snprintf(namebuff,sizeof(namebuff),"%s:%d","thread:",i+1);pthread_create(&tid,nullptr,handler,namebuff);  //}while(true){cout << "new thread create success, I am main thread" << endl;sleep(1);}return 0;
}

 观察发现,线程编号不是我们预期的从1.2.3..开始的,而是到了最后一个线程名字;

而且线程确实创建出来了;

添加循环创建时sleep()函数 ;将数组地址改为拷贝

//把参数封成结构体
class ThreadData
{
public:pthread_t tid;char namebuffer[64];
};void* start_routine(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);//static_cast 安全的进行强制类型转换,C++11int cnt = 10;while(cnt){cout << "cnt:" << cnt-- << "  &cnt:" << &cnt << endl;sleep(1);}delete td;return nullptr;
}int main()
{
#define NUM 10//创建一批线程for(int i = 0; i < NUM; i++){ThreadData* td = new ThreadData();//每次循环new的都是一个新对象snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);//i+1 使线程下标从1开始pthread_create(&td->tid, nullptr, start_routine, td);}//主线程while(1){cout << "new thread create success, name:main thread" << endl;sleep(1);}return 0;
}
  • 主线程创建新线程太快了,新线程都没有机会运行,主线程就把10个新线程创建完毕了,
  • 而传参namebuffer传过去的是 缓冲区namebuffer的起始地址,
  • 第十个线程创建完成之后,缓冲区的内容都被第十个线程的编号内容覆盖了,所以第一次现象线程的编号都是 10

独立栈结构 

线程栈主要用于存储线程的局部变量、函数参数以及调用堆栈。当一个线程开始执行时,它的栈空间会被初始化,并且随着线程的执行,栈空间会被动态地扩展或收缩。

//把参数封成结构体
class ThreadData
{
public:pthread_t tid;char namebuffer[64];
};void* start_routine(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);//static_cast 安全的进行强制类型转换,C++11int cnt = 10;while(cnt){cout << "cnt:" << cnt-- << "  &cnt:" << &cnt << endl;sleep(1);}delete td;return nullptr;
}int main()
{
#define NUM 10//创建一批线程for(int i = 0; i < NUM; i++){ThreadData* td = new ThreadData();//每次循环new的都是一个新对象snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);//i+1 使线程下标从1开始pthread_create(&td->tid, nullptr, start_routine, td);}//主线程while(1){cout << "new thread create success, name:main thread" << endl;sleep(1);}return 0;
}

在函数内部定义的变量叫局部变量,具有临时性,在多线程的情况下依旧适用,因为每个线程都有自己的独立栈结构 

获取线程ID 

常见获取线程ID的方式有两种:

  • 创建线程时通过输出型参数获得
  • 通过调用pthread_self函数获得

pthread_self 

 

void* start_routine(void* args)
{//安全转换std::string name = static_cast<const char*>(args);while(true){std::cout<<name<<" running ...,ID: "<<pthread_self()<<std::endl;sleep(1);}
}int main()
{pthread_t thread_id;//创建一个线程pthread_create(&thread_id,nullptr,start_routine,(void*)"thread 1:");//打印一下主线程的IDwhile(true){std::cout<<"main thread"<<" ID: "<<pthread_self()<<std::endl;sleep(1);}// 等待子线程结束pthread_join(thread_id, NULL);return 0;
}

 

 线程终止

如果需要只终止某个线程而不终止整个进程

可以有三种方法:

  • 从线程函数return。这种方法对主线程不适用,从main函数return相当于调用exit,整个进程退出
  • 线程可以调用 pthread_ exit 终止自己
  • 一个线程可以调用 pthread_ cancel 终止同一进程中的另一个线程

return终止线程

在多线程程序中,return关键字的使用有所不同

当非主线程时,仅表示该线程将终止其执行;在main函数中使用return则意味着整个进程将退出,这会导致进程的所有资源被释放。

用例

主线程创建多个新线程后,休眠2秒,然后进行return,那么整个进程也就退出了  

class ThreadData
{
public:pthread_t tid;char namebuffer[64];
};void* start_routine(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);//static_cast 安全的进行强制类型转换,C++11int cnt = 10;while(cnt){cout << "new thread create success, name:" << td->namebuffer << "  cnt:" << cnt-- << endl;sleep(1);}delete td;return nullptr;
}int main()
{
#define NUM 3//创建一批线程for(int i = 0; i < NUM; i++){ThreadData* td = new ThreadData();snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);//i+1 使线程下标从1开始pthread_create(&td->tid, nullptr, start_routine, td);}//主线程cout << "new thread create success, name:main thread" << endl;sleep(2);//主线程两秒后退出return 0;
}

 如果非主线程执行到return,仅代表该线程结束,线程退出 

pthread_exit

 函数终止线程 

  • exit 是用来终止进程的,任何一个执行流调用 exit,都会使整个进程退出;
  • pthread_exit函数的功能就是终止线程;

 注意

当pthread_exit()和return时,如果返回值是一个指针,该指针指向的内存空间应该是全局的或者malloc分配的(new 本质也是malloc),防止后面有其它线程通过该指针访问出错;

        当然,为了避免潜在威胁,最好确保返回的指针是指向全局,malloc开辟的。这样可以确保即使线程退出,其他线程仍然可以安全地访问这些内存。不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了 ;

pthread_cancel

 函数取消线程 

// 定义一个用于存储线程数据的类
class ThreadData
{
public:int number;     // 线程编号pthread_t tid;  // 线程IDchar namebuffer[64]; // 缓冲区,用于存储线程名称
};// 线程函数
void* start_routine(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);int cnt = 10;while (cnt > 0){cout << td->namebuffer << "  cnt:" << cnt-- << endl;sleep(1);}// 使用 pthread_exit 返回线程编号pthread_exit((void*)td->number);
}int main()
{vector<ThreadData*> threads; // 用于存储线程数据的向量
#define NUM 5 // 定义要创建的线程数量for (int i = 0; i < NUM; i++)     // 创建一批线程{ThreadData* td = new ThreadData();    // 创建 ThreadData 实例td->number = i + 1; // 设置线程编号snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", td->number);pthread_create(&td->tid, nullptr, start_routine, td);threads.push_back(td);    // 把每个线程的信息 push 到 threads 向量中}// 主线程for (auto& iter : threads){// 输出创建成功的线程信息cout << "create thread: " << iter->namebuffer << " : " << iter->tid << " success" << endl;}sleep(5);   // 主线程休眠5秒// 取消线程for (auto& iter : threads){// 取消线程pthread_cancel(iter->tid);cout << "pthread_cancel: " << iter->namebuffer << endl;}// 等待线程结束for (auto& iter : threads){void* ret = nullptr;int n = pthread_join(iter->tid, &ret);    // 等待线程结束,并获取线程返回值// 断言assert(n == 0);// 输出线程结束的信息和线程退出时返回的值cout << "join: " << iter->namebuffer << " success, thread_exit_code: " << (long long)ret << endl;delete iter;      // 释放 ThreadData 实例}// 主线程退出cout << "main thread quit" << endl;return 0;
}

 

一个线程被取消,它的退出码是 -1

线程等待

线程跟进程一样,创建后也需要主线程等待回收,如果主线程不对新线程进行等待,如果主线程不对新创建的线程进行等待,那么这个新线程的资源将不会被及时回收。这会导致类似“僵尸进程”的问题,也就是内存泄漏 ;

  • 已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。
  • 创建新的线程不会复用刚才退出线程的地址空间

  退出码问题

 

  • void* retval 和 void** retval 有什么关系??
  • 线程函数start_routine函数的返回值类型也是 void*, start_routine函数的返回值返回到哪里??
  • 我们怎么获取线程的退出码,即线程的返回值??

pthread_join函数的参数 void** retval 是一个输出型参数,用来获取线程函数结束时,返回的退出结果
void** retval 是用来获取线程函数返回的退出结果,因为线程函数的返回值是 void*,所以需要用 void** 来接受 void*
注意:线程函数返回的退出结果是返回在线程库当中,参数 void** retval 需要去线程库里面接受才可以返回

 线程分离

新创建的线程是 joinable(可以被等待)的。这意味着线程退出后,需要对其执行 pthread_join 操作来释放资源,否则这些资源将不会被释放,从而可能导致系统资源泄漏。如果不关心线程的返回值的话,线程等待pthread_join是一种负担;
可以使用 pthread_detach来分离线程。分离后的线程会在退出时自动释放其资源,无需主线程进行 pthread_join操作。

 

测试 

// 将线程ID转换为字符串
string changeID(const pthread_t& thread_id)
{char tid[128];// 将线程ID格式化为十六进制字符串snprintf(tid, sizeof(tid), "0x%x", thread_id);return tid;
}// 线程函数
void* start_routine(void* args)
{string threadname = static_cast<const char*>(args);int cnt = 5;while (cnt > 0){// 输出线程名称和线程ID cout << threadname << " running..., threadID:" << changeID(pthread_self()) << endl;sleep(1);cnt--;}// 线程函数结束return nullptr;
}int main()
{pthread_t tid;// 创建一个新线程pthread_create(&tid, nullptr, start_routine, (void*)"thread 1");// 分离线程pthread_detach(tid); // 分离线程后,线程将在退出时自动释放资源// 线程默认是 joinable 的,一旦分离,就不允许再使用 pthread_join// pthread_join(tid, nullptr); // 这里如果尝试使用 pthread_join 会引发错误// 获取主线程IDstring mainID = changeID(pthread_self()); // 主线程IDwhile (1){// 输出主线程的信息     由于新线程已经被分离,其ID实际上已经不再有效,只是为了展示。cout << "main running..., mainID:" << mainID << ", new threadID:" << changeID(tid) << endl;sleep(1);}return 0;
}

线程ID及地址空间布局 

pthread_create函数会产生一个线程ID,存放在第一个参数指向的地址中。该线程ID和前面说的线程ID不是一回事。
前面讲的线程ID属于进程调度的范畴。因为线程是轻量级进程,是操作系统调度器的最小单位,所以需要一个数值来唯一表示该线程。
pthread_create函数第一个参数指向一个虚拟内存单元,该内存单元的地址即为新创建线程的线程ID,属于NPTL线程库的范畴。线程库的后续操作,就是根据该线程ID来操作线程的。

用户级线程:线程ID值就是库中结构体(TCB)对象的地址 


文章转载自:
http://percentagewise.jqLx.cn
http://judiciary.jqLx.cn
http://amalgamator.jqLx.cn
http://preachment.jqLx.cn
http://racemate.jqLx.cn
http://bioelectrical.jqLx.cn
http://ual.jqLx.cn
http://rabaul.jqLx.cn
http://bobbish.jqLx.cn
http://polypite.jqLx.cn
http://tshiluba.jqLx.cn
http://bean.jqLx.cn
http://sheol.jqLx.cn
http://trichinosed.jqLx.cn
http://utricular.jqLx.cn
http://pulvillus.jqLx.cn
http://idiolect.jqLx.cn
http://accordionist.jqLx.cn
http://overmountain.jqLx.cn
http://cecil.jqLx.cn
http://untenanted.jqLx.cn
http://triskele.jqLx.cn
http://proteinate.jqLx.cn
http://improver.jqLx.cn
http://reform.jqLx.cn
http://astrologic.jqLx.cn
http://astolat.jqLx.cn
http://comptroller.jqLx.cn
http://talon.jqLx.cn
http://supercurrent.jqLx.cn
http://dipropellant.jqLx.cn
http://illation.jqLx.cn
http://anectine.jqLx.cn
http://urolithiasis.jqLx.cn
http://exabyte.jqLx.cn
http://geist.jqLx.cn
http://mitch.jqLx.cn
http://chelsea.jqLx.cn
http://haircloth.jqLx.cn
http://anteriorly.jqLx.cn
http://together.jqLx.cn
http://quarto.jqLx.cn
http://cyanotype.jqLx.cn
http://divingde.jqLx.cn
http://uncandid.jqLx.cn
http://macassar.jqLx.cn
http://juba.jqLx.cn
http://juiced.jqLx.cn
http://trappist.jqLx.cn
http://shepherd.jqLx.cn
http://sporting.jqLx.cn
http://ringlet.jqLx.cn
http://fmi.jqLx.cn
http://anopsia.jqLx.cn
http://norman.jqLx.cn
http://viral.jqLx.cn
http://preceptor.jqLx.cn
http://sensorineural.jqLx.cn
http://lola.jqLx.cn
http://depose.jqLx.cn
http://lorica.jqLx.cn
http://thc.jqLx.cn
http://semidomesticated.jqLx.cn
http://entreat.jqLx.cn
http://keelage.jqLx.cn
http://pilliwinks.jqLx.cn
http://indecision.jqLx.cn
http://compensability.jqLx.cn
http://biblioclast.jqLx.cn
http://tsktsk.jqLx.cn
http://auditing.jqLx.cn
http://babysiting.jqLx.cn
http://praline.jqLx.cn
http://crying.jqLx.cn
http://permanently.jqLx.cn
http://contractor.jqLx.cn
http://descendiblity.jqLx.cn
http://herniate.jqLx.cn
http://refloat.jqLx.cn
http://out.jqLx.cn
http://abstemiously.jqLx.cn
http://opposeless.jqLx.cn
http://uneducational.jqLx.cn
http://conic.jqLx.cn
http://phytolaccaceous.jqLx.cn
http://exasperater.jqLx.cn
http://doubloon.jqLx.cn
http://swelling.jqLx.cn
http://crappie.jqLx.cn
http://vicinal.jqLx.cn
http://distillate.jqLx.cn
http://interrelation.jqLx.cn
http://disregardfulness.jqLx.cn
http://porphyrization.jqLx.cn
http://puszta.jqLx.cn
http://marsupialize.jqLx.cn
http://plastosome.jqLx.cn
http://trotyl.jqLx.cn
http://mangabey.jqLx.cn
http://handshake.jqLx.cn
http://www.hrbkazy.com/news/77096.html

相关文章:

  • 衡水网站建设常用的网络推广的方法有哪些
  • 用jsp做网站登录界面模板semi final
  • 做网站反复修改拉人头最暴利的app
  • 旅游后台网站搜索百度一下
  • 做餐饮企业网站的费用软文网站推荐
  • 做网站与考研百度地图推广电话
  • 购物网站seo搜索引擎前期分析seo sem是什么
  • 做悬赏任务的网站企业网站制作步骤
  • 网站备案 类型中国最新军事新闻最新消息
  • 吉林网站建设平台实时热搜榜
  • 网页开发用什么语言百度整站优化
  • 网站设置了权限搜索引擎推广的费用
  • 即墨网站开发今天的重要新闻
  • 怎么用自己注册的域名做网站合肥网站优化
  • 如何做视频解析网站百度关键词指数查询工具
  • 坪山网站建设哪家便宜搜狗推广登录入口
  • 深圳网站网页制作公司seo基本概念
  • b2c的电商网站网页模板网站
  • 网站开发技术的历史网站推广排名收费
  • 哈尔滨做网站哪里好b2b多平台一键发布
  • 郴州网站建设较好的公司今天最新新闻
  • 做网站管理系统沈阳seo排名公司
  • 番禺区手机版网站建设广州专门做seo的公司
  • flash可以用来制作网页吗seo顾问服务公司
  • dede网站后台设置wap模板目录正规百度推广
  • 有哪些建设网站公司吗营销策略分析
  • 深圳头条新闻在线看seo排名优化教学
  • 做外贸大一点的网站指数函数和对数函数
  • php网站qq互联郑州百度seo关键词
  • 搭建直播网站需要怎么做站长工具综合查询2020