• 为什么类中的线程函数必须要声明静态


    其实类的静态函数就跟全局函数是一个样子的, 只是调用的时候要加下个类修饰符而已.

    至于为什么不能是非静态成员函数呢, 因为非静态成员函数都会在参数列表中加上一个this指针为为参数, 这样的话你写的线程函数就不符合调用规定了.
    比如 DWORD WINAPI ThreadFun(LPVOID); 是非静态的,实际编译后,就会变成
    DWORD WINAPI ThreadFun(LPVOID, CMyClass *this);
    这个函数就明显不能作为线程的函数了, 因为多了个参数.所以编译就过不了了.

    参考地址:http://www.cnblogs.com/diegodu/p/4655036.html

    它与设置成全局函数有一个好处:就是不用声明为friend成员即可访问对象的私有成员。
    成员变量不用改成static的,你创建线程的时候把对象的“this”指针作为参数传递过去,就可访问了。

    #include <pthread.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    class Thread
    {
        private:
            pthread_t pid;
        private:
            static void * start_thread(void *arg);// //静态成员函数
        public: 
            int start();
            virtual void run() = 0; //基类中的虚函数要么实现,要么是纯虚函数(绝对不允许声明不实现,也不纯虚)
    };
    
    int Thread::start()
    {
        if(pthread_create(&pid,NULL,start_thread,(void *)this) != 0) //´创建一个线程(必须是全局函数)
        {    
            return -1; 
        }    
        return 0;
    }
    
    void* Thread::start_thread(void *arg) //静态成员函数只能访问静态变量或静态函数,通过传递this指针进行调用
    {
        Thread *ptr = (Thread *)arg;
        ptr->run();  //线程的实体是run
    }
    
    
    
    class MyThread:public Thread
    {
        public: 
            void run();
    };
    void MyThread::run()
    {
        printf("hello world
    ");
    }
    
    int main(int argc,char *argv[])
    {
        MyThread myThread;
        myThread.start();
        //test.run();
        sleep(1);
        return 0;
    }

    编译运行:

    diego@ubuntu:~/myProg/pthreadCpp$ g++ main.cpp -lpthread
    diego@ubuntu:~/myProg/pthreadCpp$ ./a.out 
    hello world
    diego@ubuntu:~/myProg/pthreadCpp$ 

    参考地址:http://bbs.csdn.net/topics/280040692

    有一个更加好的方法,就是使用boost::thread,结合boost::function,boost::bind很方便的实现类成员函数线程化

    1.如何创建简单的线程

    #include <boost/thread/thread.hpp>
    #include <iostream>
    using namespace std;
     
    void helloworld()
    {
        cout << "hello world" << endl;
    }
     
    int _tmain(int argc, _TCHAR* argv[])
    {
        boost::thread thd(&helloworld);
        thd.join();//等线程结束
    }

    2.如何给线程携带参数

    #include <boost/thread/thread.hpp>
    #include <boost/bind.hpp>
    #include <string>
    #include <iostream>
    using namespace std;
     
    void helloworld(string par1, int par2, double par3)
    {
        cout << "hello world" << endl;
        cout << par1 << "," << par2 << "," << par3 << endl;
    }
     
    int _tmain(int argc, _TCHAR* argv[])
    {
        boost::thread thd(boost::bind(&helloworld,string("haha"),1,1.0));
        thd.join();//等线程结束
    }

    3.如何线程互斥

    #include <boost/thread/thread.hpp>
    #include <boost/thread/mutex.hpp>
    #include <iostream>
    using namespace std;
     
    boost::mutex mutex_;
    int io_;
    void thread_in()
    {
        boost::mutex::scoped_lock lock(mutex_);
        cout << "in " << io_++ << endl;
    }
    void thread_out()
    {
        boost::mutex::scoped_lock lock(mutex_);
        cout << "out " << io_-- << endl;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        boost::thread thd1(&thread_in);
        boost::thread thd2(&thread_out);
        thd1.join();
        thd2.join();
        io_ = 0;
     
    }

    4.如何让类成员函数线程化

    #include <boost/thread/thread.hpp>
    #include <string>
    #include <iostream>
    using namespace std;
     
    class myclass
    {
    public:
        myclass():
          classname_("I am Hero")
        {
     
        }
    protected:
        string classname_;
    protected:
        void handle_thread()
        {
            cout << classname_ << endl;
        }
    };
     
    int _tmain(int argc, _TCHAR* argv[])
    {
        myclass c;
        boost::thread thd(boost::bind(&myclass::handle_thread,&c));
        thd.join();
    }
  • 相关阅读:
    Centos7.3防火墙配置
    Centos7使用yum安装MySQL5.6的正确姿势
    Connect C# to MySQL
    ADO.NET操作MySQL数据库
    Mac OS 上 VIM 8.0 安装体验
    WebSocket实战之————Workerman服务器的安装启动
    C语言实现文件复制功能(包括文本文件和二进制文件)
    Gateway/Worker模型 数据库使用示例
    [转]Using the Group Pane to Repeat Page Titles
    [转]学习 WCF (6)--学习调用WCF服务的各种方法
  • 原文地址:https://www.cnblogs.com/suntp/p/6473118.html
Copyright © 2020-2023  润新知