方法一: 代理线程函数(proxyThreadFunc)作为类的静态成员函数, 回调函数指针作为类的私有成员变量

方法二: 代理线程函数(proxyThreadFunc)作为全局函数,  回调函数指针作为自定义结构体的成员

Noncopyable.h:

 #ifndef _Noncopyable_H_
#define _Noncopyable_H_ class Noncopyable
{
public:
Noncopyable(){}
~Noncopyable(){} private:
Noncopyable(const Noncopyable & a){}
void operator=(const Noncopyable & a){}
}; #endif

Thread.h:

 #ifndef _Thread_H_
#define _Thread_H_ #include "Noncopyable.h"
#include <functional>
#include <pthread.h> /*====================
====================*/ class Thread : public Noncopyable
{
public:
typedef std::function<void ()> ThreadFunc;
Thread(ThreadFunc func)
:thread_id(), running_status(-), callback_func(func)
{}
virtual ~Thread()
{
if(!running_status)
pthread_detach(thread_id);
} virtual void start() = ;
virtual void join() = ; protected:
pthread_t thread_id;
int running_status;
ThreadFunc callback_func;
}; /*====================
====================*/ class ThreadStruct : public Thread
{
public:
ThreadStruct(ThreadFunc func)
:Thread(func)
{}
~ThreadStruct(){} virtual void start() override;
virtual void join() override;
}; /*====================
====================*/ class ThreadStatic : public Thread
{
public:
ThreadStatic(ThreadFunc func)
:Thread(func)
{}
~ThreadStatic(){} virtual void start() override;
virtual void join() override; private:
static void * proxyThreadFunc(void *);
}; #endif

Thread.cpp:

 #include "Thread.h"

 /*====================
====================*/ struct ThreadData
{
typedef Thread::ThreadFunc ThreadFunc;
ThreadFunc cbfunc; ThreadData(ThreadFunc func)
:cbfunc(func)
{} void runThread()
{
cbfunc();
}
}; void * proxyThreadFunc(void * arg)
{
ThreadData * pd = NULL;
pd = static_cast<ThreadData *>(arg);
pd->runThread();
delete pd;
return NULL;
} void ThreadStruct::start()
{
ThreadData * td = NULL;
td = new ThreadData(callback_func);
if(pthread_create(&thread_id, NULL, proxyThreadFunc, td) < )
delete td;
} void ThreadStruct::join()
{
pthread_join(thread_id, NULL);
} /*====================
====================*/ void * ThreadStatic::proxyThreadFunc(void * arg)
{
ThreadStatic * pd = NULL;
pd = static_cast<ThreadStatic *>(arg);
pd->callback_func();
return NULL;
} void ThreadStatic::start()
{
pthread_create(&thread_id, NULL, proxyThreadFunc, this);
} void ThreadStatic::join()
{
pthread_join(thread_id, NULL);
}

ThreadMain.cpp:

 #include "Thread.h"

 #include <iostream>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h> using namespace std; class Test
{
public:
void foo()
{
cout << "foo()" << endl;
} void bar(int i)
{
cout << "bar(" << i << ")" << endl;
}
}; /*====================
====================*/ class TestThread
{
public:
TestThread()
:cnt(), pThread(NULL)
{} void threadFunc()
{
while(cnt < )
{
sleep();
cout << "cnt = " << ++cnt << endl;
}
} void start()
{
pThread->start();
} void join()
{
pThread->join();
} void attach(Thread * th)
{
pThread = th;
} private:
int cnt;
Thread * pThread; //类的组合
}; /*====================
====================*/ int main()
{
Thread * p1, * p2;
TestThread tt;
tt.attach(new ThreadStatic(bind(&TestThread::threadFunc, &tt)));
Test test;
p1 = new ThreadStruct(bind(&Test::foo, &test));
p2 = new ThreadStatic(bind(&Test::bar, &test, )); tt.start();
p1->start();
p2->start();
tt.join();
p1->join();
p2->join();
delete p1;
delete p2;
}

封装Thread的两种方法 via C++ in Linux的更多相关文章

  1. C# web api返回类型设置为json的两种方法

    web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Applic ...

  2. 使用PHP发送邮件的两种方法

    使用PHP发送邮件的两种方法 May242013 作者:Jerry Bendy   发布:2013-05-24 22:25   分类:PHP   阅读:2,107 views   抢沙发     今天 ...

  3. hive权威安装出现的不解错误!(完美解决)两种方法都可以

    以下两种方法都可以,推荐用方法一! 方法一: 步骤一: yum -y install mysql-server 步骤二:service mysqld start 步骤三:mysql -u root - ...

  4. HibernateTemplate、HibernateDaoSupport两种方法实现增删改查Good(转)

    Spring+Hibernate两种方法实现增删改查 首先,定义一个Customer的bean类,设置好Customer.hbm.xml文件.再定义好一个Dao接口.准备好一个jdbc.propert ...

  5. C++调用DLL有两种方法——静态调用和动态调用

    C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报  分类: cpp(30)  [ ...

  6. C模块回调Lua函数的两种方法

    作者:ani_di 版权所有,转载务必保留此链接 http://blog.csdn.net/ani_di C模块回调Lua函数的两种方法 lua和C通过虚拟栈这种交互方式简单而又可靠,缺点就是C做栈平 ...

  7. 在Delphi中使用C++对象(两种方法,但都要改造C++提供的DLL)

    Delphi是市场上最好的RAD工具,但是现在C++占据着主导地位,有时针对一个问题很难找到Delphi或Pascal的解决方案.可是却可能找到了一个相关的C++类.本文描述几种在Delphi代码中使 ...

  8. 原生Js 两种方法实现页面关键字高亮显示

    原生Js 两种方法实现页面关键字高亮显示 上网看了看别人写的,不是兼容问题就是代码繁琐,自己琢磨了一下用两种方法都可以实现,各有利弊. 方法一 依靠正则表达式修改 1.获取obj的html2.统一替换 ...

  9. 在Java Web程序中使用监听器可以通过以下两种方法

    之前学习了很多涉及servlet的内容,本小结我们说一下监听器,说起监听器,编过桌面程序和手机App的都不陌生,常见的套路都是拖一个控件,然后给它绑定一个监听器,即可以对该对象的事件进行监听以便发生响 ...

随机推荐

  1. Vue.js——60分钟快速入门(转)

    vue:Vue.js——60分钟快速入门 <!doctype html> <html lang="en"> <head> <meta ch ...

  2. conda环境复制

    配置环境是一个很烦的事,有时候用到服务器需要一遍又一遍的配..太麻烦了,这时候就要用到conda,直接复制已有的环境.事半功倍. 第一种方法:地址复制 首先找到要复制的环境的路径:conda info ...

  3. 上海高校程序设计联赛 D-CSL的字符串 栈模拟

    题目链接:https://ac.nowcoder.com/acm/contest/551/D ASCII码表示的字符转换成整数实测不超过200(具体多少懒得查了) 分析:要求总的字典序最小,那就让最小 ...

  4. .Net mvc 上传多文件

    .net mvc 上传多文件有很多种方式,我的方法只是其中一种, 仅供参考,我主要是注重参数传递的过程,后面文件保存的地方省略.. 调试环境 vs2017 控制器代码: [HttpPost] publ ...

  5. ThinkPHP5.0源码学习之缓存Cache(一)

    一.文件 1.缓存配置文件:thinkphp\convention.php 2.缓存文件:thinkphp\library\think\Cache.php 3.驱动目录:thinkphp\librar ...

  6. python运用turtle 画出汉诺塔搬运过程

    python运用turtle 画出汉诺塔搬运过程 1.打开 IDLE 点击File-New File 新建立一个py文件 2.向py文件中输入如下代码 import turtle class Stac ...

  7. Win10系列:C#应用控件进阶5

    多线形 多线形和多边形类似,不同点在于多线形中最后一个点和第一个点不会默认被连接.在多线形的点集中,可以存在同一个开始点和终结点因而会定义成闭合图形.下面将演示如何使用Polyline控件绘制一个多线 ...

  8. JAVA实现简单的四则运算

    GitHub 项目地址 https://github.com/745421831/-/tree/master PSP PSP2.1 Personal Software Process Stages 预 ...

  9. Nodejs搭建基于express的应用,使用脚手架工具--express-generator

    1.安装nodejs 1> 去nodejs官网下载最新nodejs安装包,地址:http://nodejs.cn/download/,选择自己适合自己电脑系统的安装包,下载下来,然后一直next ...

  10. Oracle 11g OGG mgr定期清理tail 文件

    OGG mgr定期清理tail 文件 2018-06-11 11:58 440 0 原创 GoldenGate 本文链接:https://www.cndba.cn/leo1990/article/28 ...