C++多线程编程

简介:

      C++的多线程不同于C语言的多线程,对于我这个从C转向C++的来说更是觉得很难理解;来新公司的这段时间也是一直在思考这方面的事情,近期一直在检查程序中死锁的问题;就总结以下最近对于C++多线程编程的心得吧。

      C++的多线程主要体现在两方面,一方面是对于全局数据的线程同步。我们看下面的实例

      首先我们封装一个Thread类

Thread.h 文件


#ifndef THREAD_H

#define THREAD_H



#include <pthread.h>



class Thread

{

public:

    Thread();



    int start();

    

    int stop();



    virtual void* run();



    bool join();



    const pthread_t& getID()const { return ntid; }



    virtual ~Thread(){};



private:

    Thread(const Thread&);



    static void* threadproc(void*);



    pthread_t ntid;



};

Thread.cpp 文件


#include <pthread.h>

#include "Thread.h"



Thread::Thread()

{

}



void* Thread::run()

{

      

}



int Thread::start()

{

    return pthread_create(

            &this->ntid,

            0,

            threadproc,

            static_cast<void *>(this)

            );        

}



int Thread::stop()

{

    return pthread_cancel(this->getID());

}



bool Thread::join()

{

    return pthread_join(this->getID(),0);

}



void* Thread::threadproc(void* a_param)

{

    Thread* pthread = static_cast<Thread *>(a_param);

    return pthread->run();

      然后我们新建MyThread类,继承自Thread类,以实现不同的算法。

MyThread.h


#ifndef MYTHREAD_H

#define MYTHREAD_H



#include <string>

#include "Thread.h"



class MyThread:public Thread

{

public:

    MyThread(const int n,const char* aName):mCount(n),mName(aName){};

    virtual void* run();



    int setCount(const int n);



    int setName(const char* aName);



private:

    int mCount;

    std::string mName;

};

MyThread.cpp


#include <string>

#include <stdio.h>

#include <boost/thread/thread.hpp>

#include "MyThread.h"



void* MyThread::run() 

{

    int sum = this->mCount*10;

    for(int i = 0;i < sum ;i++)

    {

        printf("%2d,the name is %s;\t\n",i,this->mName.c_str());

    }

}



int MyThread::setCount(const int n)

{

    this->mCount = n;

    return 0;

}



int MyThread::setName(const char* aName)

{

    std::string aString(aName);

    this->mName = aString;

    return 0;

main.cpp 


#include <stdio.h>

#include "MyThread.h"







int main()

{



    MyThread t1(15,"Thread 1");

        MyThread t2(12,"Thread 2");

    

    t1.start();

    t2.start();

    

    sleep(1);



    return 0;

Makefile文件,写的不好,大家见谅啊 


multiThread:main.o MyThread.o Thread.o

    g++ -o multiThread main.o MyThread.o Thread.o -lpthread



main.o:main.cpp MyThread.h

    g++ -c main.cpp



MyThread.o:MyThread.cpp MyThread.h Thread.h

    g++ -c MyThread.cpp



Thread.o:Thread.cpp Thread.h

    g++ -c Thread.cpp



clean:

       make并且运行之后,看下运行情况 为了节省空间我只给出了几个数据,有兴趣大家可以展示以下 


....

4,the name is Thread 1;    

0,the name is Thread 2;    

5,the name is Thread 1;    

....

9,the name is Thread 1;    

10,the name is Thread 1;    

1,the name is Thread 2;    

2,the name is Thread 2

      线程1和2交替在终端打印,但是如果我们添加互斥量(相当于是对终端访问的互斥量)之后会出现什么情况呢?

我们修改MyThread.cpp文件如下


#include <string>

#include <stdio.h>

#include <boost/thread/thread.hpp>

#include "MyThread.h"



pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//添加互斥量



void* MyThread::run() 

{

    pthread_mutex_lock(&mutex);  //加锁

    int sum = this->mCount*10;

    for(int i = 0;i < sum ;i++)

    {

        printf("%2d,the name is %s;\t\n",i,this->mName.c_str());

    }

    pthread_mutex_unlock(&mutex);  //解锁

}



int MyThread::setCount(const int n)

{

    this->mCount = n;

    return 0;

}



int MyThread::setName(const char* aName)

{

    std::string aString(aName);

    this->mName = aString;

    return 0;

我们可以运行一下看下打印信息,没有数据的冲突,因为数据量太大,在此不列出。

 

      C++封装的概念使不同对象之间的私有数据不会交错,这个概念是我这个从C转向C++一直无法理解,尤其是在遇见多线程的情况下,但是这并不表明私有数据不需要加锁,因为可能涉及到类中不同的方法在同时访问或者修改数据。看下面的例子

      我们将main.cpp文件修改如下, 


#include <stdio.h>

#include "MyThread.h"







int main()

{



    MyThread t1(150,"Thread 1");

    //MyThread t2(12,"Thread 2");

    

    t1.start();

    t1.setCount(12);

    //t2.start();

    

    sleep(1);



    return 0;

      将MyThread.cpp文件中的run函数也略作修改


#include <string>

#include <stdio.h>

#include <boost/thread/thread.hpp>

#include "MyThread.h"



void* MyThread::run() 

{

    for(int i = 0;i < this->mCount*10000 ;i++)

    {

        printf("%2d,the name is %s;\t\n",i,this->mName.c_str());

    }

}



int MyThread::setCount(const int n)

{

    this->mCount = n;

    return 0;

}



int MyThread::setName(const char* aName)

{

    std::string aString(aName);

    this->mName = aString;

    return 0;

   大家可以看下运行结果,在这里就不作详细说明;

      为了解决上述的冲突,我们需要在类中添加锁,为了我们修改MyThread.h MyThread.cpp 和 main.cpp函数

MyThread.h文件    


#ifndef MYTHREAD_H

#define MYTHREAD_H



#include <string>

#include "Thread.h"





class MyThread:public Thread

{

public:

    MyThread(const int n,const char* aName):mCount(n),mName(aName)

    {

        pthread_mutex_init(&mutex,NULL);

    }

    virtual void* run();



    int setCount(const int n);



    int setName(const char* aName);



private:

    int mCount;

    std::string mName;

    pthread_mutex_t mutex;

};

MyThread.cpp文件


#include <string>

#include <stdio.h>

#include <boost/thread/thread.hpp>

#include "MyThread.h"



void* MyThread::run() 

{

    pthread_mutex_lock(&mutex);

    //int sum = this->mCount*10;

    for(int i = 0;i < this->mCount*10000 ;i++)

    {

        printf("%2d,the name is %s;\t\n",i,this->mName.c_str());

    }

    pthread_mutex_unlock(&mutex);

}



int MyThread::setCount(const int n)

{

    pthread_mutex_lock(&mutex);

    this->mCount = n;

    pthread_mutex_unlock(&mutex);

    return 0;

}



int MyThread::setName(const char* aName)

{

    std::string aString(aName);

    this->mName = aString;

    return 0;

main.cpp 文件


#include <stdio.h>

#include "MyThread.h"







int main()

{



    MyThread t1(150,"Thread 1");

    

    t1.start();

    sleep(1);

    t1.setCount(12);

    t1.start();

    



    return 0;

 

       有兴趣的读者可以看下运行效果,在添加了类内部锁之后,有效的实现了数据的同步。

       欢迎讨论。 

相关文章
|
1月前
|
存储 前端开发 Java
【C++ 多线程 】C++并发编程:精细控制数据打印顺序的策略
【C++ 多线程 】C++并发编程:精细控制数据打印顺序的策略
45 1
|
1月前
|
数据可视化 关系型数据库 编译器
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
108 2
|
1月前
|
存储 前端开发 算法
C++线程 并发编程:std::thread、std::sync与std::packaged_task深度解析(一)
C++线程 并发编程:std::thread、std::sync与std::packaged_task深度解析
45 0
|
29天前
|
存储 算法 Java
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
72 0
|
1月前
|
消息中间件 Linux 调度
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
67 0
|
1月前
|
存储 并行计算 Java
C++线程 并发编程:std::thread、std::sync与std::packaged_task深度解析(二)
C++线程 并发编程:std::thread、std::sync与std::packaged_task深度解析
64 0
|
29天前
|
安全 Java 调度
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
44 2
|
29天前
|
Linux API C++
【C++ 线程包裹类设计】跨平台C++线程包装类:属性设置与平台差异的全面探讨
【C++ 线程包裹类设计】跨平台C++线程包装类:属性设置与平台差异的全面探讨
51 2
|
29天前
|
设计模式 安全 C++
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
71 2
|
1月前
|
算法 安全 Unix
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
30 0

热门文章

最新文章