shzuoxinyu93 2015-12-09 09:07 采纳率: 33.3%
浏览 605

大神帮忙看看下面多线程中关于锁的使用存在的问题

 #include <stdio.h>
#include <process.h>
#include <windows.h>
#include <string>

class IAnimalActionObserver
{
public:
    IAnimalActionObserver(){}
    virtual ~IAnimalActionObserver(){}
    virtual void OnAnimalEat() = 0;
};

class Animal
{
public:
    Animal()
        : observer_(NULL)
    {
        _beginthreadex(NULL, 0, ThreadFun, this, 0, NULL);
    }
    virtual ~Animal(){}

    virtual void RegsiterActionObserver(IAnimalActionObserver* observer)
    {
        observer_ = observer;
    }
    virtual void DeregsiterActionObserver()
    {
        observer_ = NULL;
    }

private:
    static unsigned int _stdcall ThreadFun(void* args)
    {
        (static_cast<Animal*>(args))->ThreadLoop();
        return 0;
    }
    void ThreadLoop()
    {
        while (true)
        {
            if (observer_)
            {
                observer_->OnAnimalEat();
            }
            Sleep(2 * 1000);
        }
    }

private:
    IAnimalActionObserver* observer_;
};

class Cat
    : public IAnimalActionObserver
{
    struct CatInfo
    {
        CatInfo():eat_count_(0){}
        int eat_count_;
        std::string str_msg_;
    };
public:
    Cat()
    {
        InitializeCriticalSection(&cs_);
        _beginthreadex(NULL, 0, ThreadFun1, this, 0, NULL);
        _beginthreadex(NULL, 0, ThreadFun2, this, 0, NULL);
    }
    virtual ~Cat()
    {

    }

    virtual void OnAnimalEat()
    {
        printf("cat eat a fish.\n");
        EatFinish();
    }

private:
    static unsigned int _stdcall ThreadFun1(void* args)
    {
        (static_cast<Cat*>(args))->ThreadLoop1();
        return 0;
    }
    void ThreadLoop1()
    {
        while (true)
        {
            animal_.RegsiterActionObserver(this);
            Sleep(2 * 1000);
            animal_.DeregsiterActionObserver();
            msg_.str_msg_ = "cat eating fish\n";
            msg_.eat_count_++;
            if (msg_.eat_count_ >= 5)
            {
                break;
            }
        }
    }
    static unsigned int _stdcall ThreadFun2(void* args)
    {
        (static_cast<Cat*>(args))->ThreadLoop2();
        return 0;
    }
    void ThreadLoop2()
    {
        while (true)
        {
            EnterCriticalSection(&cs_);
            if (msg_.eat_count_ >= 5)
            {
                msg_.str_msg_ = "cat eat finish\n";
                EatFinish();
                break;
            }
            LeaveCriticalSection(&cs_);
        }
    }
    void EatFinish()
    {
        EnterCriticalSection(&cs_);
        if (msg_.eat_count_ >= 5)
        {
            printf(msg_.str_msg_.c_str());
            msg_.eat_count_ = 0;
            msg_.str_msg_.empty();
            animal_.DeregsiterActionObserver();
        }
        LeaveCriticalSection(&cs_);
    }

private:
    Animal animal_;
    CRITICAL_SECTION cs_;
    CatInfo msg_;
};

int main()
{
    Cat cat_;
    while (1)
    {
        Sleep(1000);
    }
    return 0;
}
  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥60 版本过低apk如何修改可以兼容新的安卓系统
    • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
    • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
    • ¥50 有数据,怎么用matlab求全要素生产率
    • ¥15 TI的insta-spin例程
    • ¥15 完成下列问题完成下列问题
    • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
    • ¥15 YoloV5 第三方库的版本对照问题
    • ¥15 请完成下列相关问题!
    • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?