C++多線程編程

來源:互聯網
上載者:User

      C++的多線程不同於C語言的多線程,對於我這個從C轉向C++的來說更是覺得很難理解;來新公司的這段時間也是一直在思考這方面的事情,近期一直在檢查程式中死結的問題;就總結以下最近對於C++多線程編程的心得吧。

      C++的多線程主要體現在兩方面,一方面是對於全域資料的線程同步。我們看下面的執行個體

      首先我們封裝一個Thread類

Thread.h 檔案

View Code

#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 檔案

View Code

#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

View Code

#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

View Code

#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

View Code

#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檔案,寫的不好,大家見諒啊

View Code

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並且運行之後,看下運行情況 為了節省空間的我只給出了幾個資料,有興趣大家可以展示以下

View Code

....
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檔案如下

View Code

#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檔案修改如下,

View Code

#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函數也略作修改

View Code

#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檔案   

View Code

#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檔案

View Code

#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 檔案

View Code

#include <stdio.h>
#include "MyThread.h"

int main()
{

    MyThread t1(150,"Thread 1");
    
    t1.start();
    sleep(1);
    t1.setCount(12);
    t1.start();
    

    return 0;

 

       有興趣的讀者可以看下運行效果,在添加了類內部鎖之後,有效實現了資料的同步。

       歡迎討論。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.