linux线程学习(二)

1 篇文章 0 订阅
1 篇文章 0 订阅

上一个linux线程学习是不带锁的线程不安全形式,只要不用共享资源还是可以的,但实际工作中我们遇到的往往是需要保障线程的访问的.因此这里实现了一个简单的线程池,为线程池的实现提供思路。

Status类封装了环境变量与锁,作为一种状态保障线程的安全,并提供挂起,供Pthreadpool使用。

Eventloop类则用于管理方法,供Phtreadpool使用。

Pthreadpool封装了多线程,并结合Status类和Eventloop类,对外提供接口。

#ifndef STATUS_H
#define STATUS_H

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

class Status
{
public:

    static Status *&construction()
    {
        if(NULL == obj)
        {
            obj = new Status();
        }
        return obj;
    }

    virtual ~Status();

    virtual void lock();

    virtual void unlock();

    virtual void signal();

    virtual void wait();

    virtual int timedwait();

    virtual void broadcast();

public:
    static Status *obj;

private:
    Status();
    struct timeval _now;
    struct timespec _timeout;
    pthread_mutex_t _mutex;
    pthread_cond_t _cond;
};
#define status (Status::obj->construction())
#define deletestatus (delete Status::obj)

#endif // STATUS_H

#ifndef EVENTLOOP_H
#define EVENTLOOP_H
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

typedef void *(*FUNC)(void *);
typedef struct Events
{
    FUNC func;
    void *param;
    Events *next;
}Events;

class Eventloop
{
public:
    static Eventloop *&construction()
    {
        if(NULL == obj)
        {
            obj = new Eventloop();
        }
        return obj;
    }

    ~Eventloop();

    void AddEvent(FUNC func, void *param);

    void GetEvent(FUNC &func, void *¶m);

    static Eventloop *obj;

private:
    Eventloop();

    unsigned int _eventnum;
    Events *_begin;
    Events *_end;
};
#define eventloop (Eventloop::obj->construction())
#endif // EVENTLOOP_H
#ifndef PTHREADPOOL_H
#define PTHREADPOOL_H
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "Eventloop.h"

#define MAXPTHREAD 5

class Pthreadpool
{
    friend void *callback(void *);
public:
    ~Pthreadpool();

    static Pthreadpool *&construction()
    {
        if(NULL == obj)
        {
            obj = new Pthreadpool();
        }
        return obj;
    }

    int init();

    int addFunc(FUNC func, void *param);

    int run();

    bool destory();

    static Pthreadpool *obj;

private:
    explicit Pthreadpool();

    bool stop;
    unsigned int _maxnum;
    unsigned int _usable;
    unsigned int _using;
    pthread_t tid[MAXPTHREAD];
};

#define pthreadpool (Pthreadpool::obj->construction())

#endif // PTHREADPOOL_H

status.cpp:
#include "Status.h"
#include <sys/time.h>

#define TIMEWAIT 3

Status *Status::obj = NULL;

Status::Status()
{
    pthread_mutex_init(&_mutex, NULL);
    pthread_cond_init(&_cond, NULL);
}

 Status::~Status()
{
    pthread_mutex_destroy(&_mutex);
    pthread_cond_destroy(&_cond);
}

 void Status::lock()
{
    pthread_mutex_lock(&_mutex);
}

 void Status::unlock()
{
    pthread_mutex_unlock(&_mutex);
}

 void Status::signal()
{
    pthread_cond_signal(&_cond);
}

 void Status::wait()
{
    pthread_cond_wait(&_cond, &_mutex);
}

 int Status::timedwait()
{
    _timeout.tv_sec = _now.tv_sec + TIMEWAIT;
    _timeout.tv_nsec = _now.tv_usec;
    gettimeofday(&_now, NULL);
    int ret = pthread_cond_timedwait(&_cond, &_mutex, &_timeout);
    return ret;
}

 void Status::broadcast()
{
    pthread_cond_broadcast(&_cond);
}

Eventloop.cpp:
#include "Eventloop.h"
#include "Status.h"
#include <string.h>

Eventloop *Eventloop::obj = NULL;

Eventloop::Eventloop()
{
    _begin = _end = NULL;
    _eventnum = 0;
}

Eventloop::~Eventloop()
{
    Events *event;
    if(NULL != _begin)
    {
        event = _begin;
        _begin = _begin->next;
        delete event;
    }
    _eventnum = 0;
}

void Eventloop::AddEvent(FUNC func,void *param)
{
    if(NULL == func) return;

    Events *event = new Events();
    event->func = func;
    event->param = param;
    event->next = NULL;
    if(NULL == _begin)
    {
        _begin = event;
    }
    else
    {
        _end->next = event;
    }
    _end = event;
    ++_eventnum;
    printf("AddEvent : now _eventnum = %u\n",_eventnum);
}

void Eventloop::GetEvent(FUNC &func, void *¶m)
{
    if(_begin == NULL) return;

    printf("get Event!\n");
    Events *event = _begin;
    if(_begin == NULL) printf("what?!\n");
    _begin = _begin->next;
    func = event->func;
    param = event->param;
    delete event;
    --_eventnum;
    printf("DeleteEvent : now _eventnum = %u\n",_eventnum);
}

Pthreadpool.cpp:
#include "Pthreadpool.h"
#include "Status.h"
#include "Eventloop.h"
#include <errno.h>
#include <unistd.h>

Pthreadpool *Pthreadpool::obj = NULL;


Pthreadpool::Pthreadpool()
{
    _maxnum = MAXPTHREAD;
}

void *callback(void *)
{
    status->lock();
    ++pthreadpool->_usable;
    status->unlock();

    while(true)
    {
        FUNC func = NULL;
        void *param = NULL;
        status->lock();
        eventloop->GetEvent(func, param);
        if(NULL == func)
        {
            if(ETIMEDOUT == status->timedwait())
            {
                printf("tid[] = %lu timedwait.\n", pthread_self());
                --pthreadpool->_maxnum;
                --pthreadpool->_usable;
                status->unlock();
                if(pthreadpool->_maxnum == 0)
                    pthreadpool->stop = true;
                break;
            }
        }
        else
        {
            --pthreadpool->_usable;
            ++pthreadpool->_using;
        }
        status->unlock();
        if(NULL != func)
        {
            func(param);
        }
    }
    pthread_detach(pthread_self());
    printf("tid[] = %lu detach and quit.\n", pthread_self());
    if(pthreadpool->stop)
    {
        printf("I'm %lu,the last pthread,then I will send a signal.\n", pthread_self());
        status->signal();
    }

    return NULL;
}


Pthreadpool::~Pthreadpool()
{
}

int Pthreadpool::init()
{
    _usable = 0;
    _using = 0;
    stop = true;
    return 0;
}

int Pthreadpool::addFunc(FUNC func, void *param)
{
    status->lock();
    eventloop->AddEvent(func, param);
    status->unlock();
    return 0;
}

int Pthreadpool::run()
{
    stop = false;
    unsigned int i = 0;
    unsigned int num = _maxnum;
    for(;i < num; ++i)
    {
        int fail = pthread_create(&tid[i], NULL, callback, NULL);
        if(!fail)
        {
            printf("tid[%u] = %lu create successfully.\n", i, tid[i]);
        }
        else
        {
            printf("tid[%u]  create failed.\n", i);
        }
    }
    printf("_maxnum == %u\n", _maxnum);
    printf("i == %u\n", i);
    return 0;
}

bool Pthreadpool::destory()
{
    if(pthreadpool->stop = true) return false;
    status->lock();
    printf("wait pthread over.\n");
    status->wait();
    printf("pthread over!\n");
    status->unlock();

    if(NULL != status)
    {
        deletestatus;
    }

    return true;
}

main.cpp:
#include <iostream>
#include "Eventloop.h"
#include "Pthreadpool.h"
#include <unistd.h>

using namespace std;

void *test1(void *ptr)
{
    cout << "test:" << pthread_self() << " get ptr[10] and sleep 2s!" << endl;
    int *arr = static_cast<int *>(ptr);
    for(int i = 0; i < 10; ++i)
    {
        cout << arr[i] << "\t";
    }
    cout << endl;
    sleep(2);
}

void *test2(void *ptr)
{
    cout << "good good study day day up!" << endl;
    cout << endl;
}

int main(int /*argc*/, char */*argv*/[])
{
    printf("begin init!\n");
    pthreadpool->init();
    printf("end init!\n");
    int ptr[10] = {1,3,5,7};
    sleep(1);
    printf("begin add!\n");
    pthreadpool->addFunc(test1, &ptr);
    pthreadpool->addFunc(test2, NULL);
    printf("end add!\n");
    sleep(1);
    printf("begin run!\n");
    pthreadpool->run();
    printf("end run!\n");
    sleep(1);
    printf("begin destory!\n");
    pthreadpool->destory();
    printf("end destory!\n");
    cout << "Hello World!" << endl;
    return 0;
}

运行结果:
begin init!
end init!
begin add!
AddEvent : now _eventnum = 1
AddEvent : now _eventnum = 2
end add!
begin run!
tid[0] = 140676791965440 create successfully.
tid[1] = 140676783572736 create successfully.
get Event!
DeleteEvent : now _eventnum = 1
tid[2] = 140676775180032 create successfully.
test:140676791965440 get ptr[10] and sleep 2s!
get Event!
DeleteEvent : now _eventnum = 0
1	3	5	7	0	0	0	0	0	0	
good good study day day up!tid[3] = 140676766787328 create successfully.
tid[] = 140676783572736 timedwait.
tid[] = 140676783572736 detach and quit.
tid[4] = 140676758394624 create successfully.
_maxnum == 4
i == 5
end run!


begin destory!
end destory!
Hello World!

转载请注明出处:https://blog.csdn.net/qq_39937902/article/details/79572502
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值