스레드 풀 구현

WBOY
풀어 주다: 2016-07-29 08:55:39
원래의
2879명이 탐색했습니다.

1. 스레드의 세 가지 주요 동기화 메커니즘

2. 뮤텍스 잠금

2. 구현 세 가지 동기화 메커니즘 각각에 대한 래퍼 클래스

3. 스레드 풀 구현

스레드 풀이 있는 경우 동적으로 스레드를 생성하는 데는 시간이 많이 걸립니다. 사용자 요청이 오면 스레드 풀에서 유휴 스레드를 가져와서 사용자의 요청을 처리합니다. 다시 유휴 상태가 되어 다음 사용 시간을 기다립니다.

#ifdef LOCKER_H
#define LOCKER_H


#include <pthread.h>
#include <semaphore.h>

/*信号量的封装*/
class sem
{
public:
    sem()
    {
        if( sem_init( &sem_like, 0, 0))
        {
            throw std::exception();
        }
    }

    ~sem()
    {
        sem_destroy( &sem_like);
    }

    bool wait()
    {
        return sem_wait( &sem_like)== 0;
    }

    bool post()
    {
        return sem_post( &sem_like)== 0;
    }

private:
    sem_t sem_like;
}


/*互斥锁的封装*/
class locker
{
public:
    locker()
    {
        if( pthread_mutex_init( &mutex_like,NULL) !=0)
        {
            throw std::exception();
        }
    }

    ~locker()
    {
        pthread_mutex_destroy( &mutex_like);
    }

    bool lock()
    {
        return pthread_mutex_lock( &mutex_like)== 0;
    }

    bool unlock()
    {
        return pthread_mutex_unlock( &mutex_like);
    }
private:
    pthread_mutex_t mutex_like;
}



/*条件变量的封装*/
class cond
{
public:
    cond()
    {
        if( pthread_mutex_init( &mutex_like,NULL)!= 0)
        {
            throw std::exception;
        }

        if( pthread_cond_init( &cond_like, NULL)!= 0)
        {
            //释放对应的互斥锁
            pthread_mutex_destroy( &mutex_like);
            throw std::exception;
        }
    }

    ~cond()
    {
        pthread_mutex_destroy( &mutex_like);
        pthread_cond_destroy( &cond_like);
    }

    bool wait()
    {
        int flag= 0;
        pthread_mutex_lock( &mutex_like);
        flag= pthread_cond_wait( &cond_like, &mutex_like);
        pthread_mutex_unlock( &mutex_like);
        return flag== 0;

    }

    bool signal()
    {
        return pthread_cond_signal( &cond_like)== 0;
    }

private:
    pthread_mutex_t mutex_like;
    pthread_cond_t cond_like;
}

#endif
로그인 후 복사

두 가지 핵심 데이터 구조가 있습니다: 스레드 컨테이너와 요청 큐


1. 스레드 컨테이너


벡터가 사용됩니다. here 스레드 풀의 모든 스레드 ID를 저장하는 컨테이너

2. 요청 대기열


여기서 목록 컨테이너는 모든 요청을 저장하는 데 사용되며 요청 처리는 FIFO 순서입니다.


참고: 1. 여기 스레드 풀 모델에서 각 스레드는 요청에 해당합니다.

#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <list>
#include <cstdio>
#include <exception>
#include <pthread.h>
#include "locker.h"

template< typename T >
class threadpool
{
public:
    threadpool( int thread_number = 8, int max_requests = 10000 );
    ~threadpool();
    bool append( T* request );

private:
    static void* worker( void* arg );
    void run();

private:
    int thread_number_like;//当前线程池中的线程个数
    int max_requests_like;//最大请求数
    //pthread_t* threads_like;
    vector< pthread> threads_like;//线程容器
    std::list< T* > workqueue_like;//请求队列
    locker queuelocker_like;//请求队列的访问互斥锁
    sem queuestat_like;//用于请求队列与空闲线程同步的信号量
    bool stop_like;//结束所有线程,线程池此时没有线程
};

template< typename T >
threadpool< T >::threadpool( int thread_number, int max_requests ) : 
        m_thread_number( thread_number ), m_max_requests( max_requests ), m_stop( false ), m_threads( NULL )
{
    if( ( thread_number <= 0 ) || ( max_requests <= 0 ) )
    {
        throw std::exception();
    }
  
    threads_like.resize( thread_number_like);
    if( thread_number_like!=  threads_like.size() )
    {
        throw std::exception();
    }

    for ( int i = 0; i < thread_number_like; ++i )
    {
        printf( "create the %dth thread\n", i );
        if( pthread_create( &threads_like [i], NULL, worker, this ) != 0 )//创建线程
        {
            threads_like.resize(0);
            throw std::exception();
        }
        if( pthread_detach( m_threads[i] ) )//设置为脱离线程
        {
            threads_like.resize(0);
            throw std::exception();
        }
    }
}

template< typename T >
threadpool< T >::~threadpool()
{
    stop_like = true;
}

template< typename T >
bool threadpool< T >::append( T* request )
{
    queuelocker_like.lock();
    if ( workqueue_like.size() > max_requests_like )
    {
        queuelocker_like.unlock();
        return false;
    }
    workqueue_like.push_back( request );
    queuelocker_like.unlock();
    queuestat_like.post();
    return true;
}

template< typename T >
void* threadpool< T >::worker( void* arg )
{
    threadpool* pool = ( threadpool* )arg;//静态函数要调用动态成员run,必须通过参数arg得到
    pool->run();//线程的执行体
    return pool;
}

template< typename T >
void threadpool< T >::run()
{
    while ( ! m_stop )
    {
        queuestat_like.wait();
        queuelocker_like.lock();
        if ( workqueue_like.empty() )
        {
            queuelocker_like.unlock();
            continue;
        }
        T* request = workqueue_like.front();
        workqueue_like.pop_front();
        queuelocker_like.unlock();
        if ( ! request )
        {
            continue;
        }
        request->process();//执行当前请求所对应的处理函数
    }
}

#endif
로그인 후 복사
2. 이 방법은 사용자 요청이 한 요청의 처리 지연이 시스템의 다른 요청 처리에 영향을 미치지 않기 때문에 이 모델에서는 요청 처리 프로세스가 비차단적일 것을 요구하지 않기 때문에 처리 기능의 성능 요구 사항이 더 적습니다. 물론 스레드 수는 동적으로 증가해야 합니다.)

3. 이 방법은 다중 사용자 요청에 응답하는 nginx와 유사한 프로세스가 더 유리합니다. 1. 프로세스 수가 고정되어 있습니다. 동시에 많은 스레드나 프로세스가 있기 때문에 너무 많은 메모리를 차지하지 않습니다. 2: nginx 작업 프로세스 수는 일반적으로 CPU 코어 수와 일치하며 프로세스를 코어에 바인딩할 수 있으므로 프로세스 전환이나 스레드 전환으로 인한 시스템 오버헤드가 절약됩니다

 


위에서는 스레드 풀의 구현을 소개했으며, PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿