[并发并行]_[任务停止]_[使用Pthread的线程本地存储来停止任务执行]
2017-02-28 14:20
726 查看
场景
1.多线程应用里, 线程基本上都是出自线程池, 那么基本不能使用pthread_cancel这类API, 因为它会终止线程运行, 线程终止后不能再次循环使用, 这对性能要求高的软件时基本是不会用pthread_cancel来停止逻辑运行的.2.自行设计的可预测伪线程停止,其实就是停止执行当前的业务逻辑,并不是终止线程, 让线程回归线程池. 目前我发现的方案基本上离不开对状态变量的判断. (比较忙, 没有参考那些其他大公司的开源项目, 如有不足,请批评指正), 这里只说我发现的一种方案, 使用specific data,线程本地存储.
说明
1.pthread也可以类似Win32一样使用线程本地存储, 使用方式是差不多的, 参考线程本地存储. 关键的地方就是创建一个默认key来存储任务对象, 通过判断任务对象的值来中断逻辑执行. 大部分情况下是线程A 正在执行逻辑A, 线程B接收到客户终止任务执行请求, 通过获取到这个任务对象A, 并修改任务对象A的状态, 这时线程A 判断到任务对象A的状态时Abort时, 退出执行循环.例子
// test-pthread-stop.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <Windows.h> #include <iostream> #include <stdint.h> #include "pthread.h" pthread_key_t gTaskKey; typedef enum kTaskStatus1 { kTaskStatusOk = 0, kTaskStatusDoing, kTaskStatusAbort, kTaskStatusFinish }kTaskStatus; struct IPCPacket { uint64_t _id; //Packet id uint8_t status; //Packet 状态 uint32_t command_type; //Packet 命令类型 void* data; //接收和发送数据. uint32_t data_length; //数据长度. }; static bool TestIsAbort(){ void* data = pthread_getspecific(gTaskKey); // pthread specific data 默认是 NULL. IPCPacket* packet = (IPCPacket*)data; if(packet && packet->status == kTaskStatusAbort) return true; return false; } static void DoWork(void* data){ for(int i = 0; ; ++i){ Sleep(1000); if(TestIsAbort()){ std::cout << "StartThread Abort: " << i << std::endl; break; }else{ std::cout << "StartThread: " << i << std::endl; } } } void* StartThread(void* data){ IPCPacket* task = (IPCPacket*)data; pthread_setspecific(gTaskKey,task); DoWork(data); return NULL; } void TestThreadAbort(){ pthread_key_create(&gTaskKey,NULL); IPCPacket task; memset(&task,0,sizeof(task)); int count = 0; pthread_t t1; pthread_create(&t1,NULL,StartThread,&task); Sleep(3000); task.status = kTaskStatusAbort; pthread_join(t1,NULL); } int _tmain(int argc, _TCHAR* argv[]) { std::cout << "TestThreadAbort Begin" << std::endl; TestThreadAbort(); std::cout << "TestThreadAbort End" << std::endl; system("pause"); return 0; }
输出:
TestThreadAbort Begin StartThread: 0 StartThread: 1 StartThread Abort: 2 TestThreadAbort End
参考
Programming With POSIX Threads相关文章推荐
- [并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)-win32线程和pthread线程比较]
- [并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)-win32线程和pthread线程比较]
- [并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例]
- [并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例]
- [并发并行]_[线程模型]_[Pthread线程使用模型之二 工作组work crew]
- [并发并行]_[线程模型]_[Pthread线程使用模型之二 工作组work crew]
- 使用ThreadPoolExecutor并行执行独立的单线程任务
- [并发并行]_[线程模型]_[Pthread线程使用模型之三 客户端/服务端模型(Client/Server]
- [并发并行]_[线程模型]_[Pthread线程使用模型之三 客户端/服务端模型(Client/Server]
- [并发并行]_[线程模型]_[Pthread线程使用模型之一管道Pipeline]
- [并发并行]_[pthread]_[对工作线程进行简单控制-暂停-继续-停止]
- [并发并行]_[线程模型]_[Pthread线程使用模型之一管道Pipeline]
- [并发并行]_[pthread]_[对工作线程进行简单控制-暂停-继续-停止]
- Java中使用ThreadPoolExecutor并行执行独立的单线程任务
- 使用ThreadPoolExecutor并行执行独立的单线程任务
- Java中使用ThreadPoolExecutor并行执行独立的单线程任务
- 使用java并发工具栅栏(CyclicBarrier)实现多线程等待,同一时刻执行共同任务
- 并发编程 09—— 任务取消 之 停止基于线程的服务
- [POSIX线程模型]_[使用pthread对工作线程进行简单控制-暂停-继续-停止]
- 使用 Task 替换 ThreadPool ,异步监测所有线程(任务)是否全部执行完毕