QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 944|回复: 4

C++线程同步

[复制链接]
发表于 2004-4-23 16:54:23 | 显示全部楼层 |阅读模式
我的上次提出的问题 C++中的通信问题,我想把这个帖子发在上一篇的后面,但是贴不上去,只好又起了一个新贴
LinuxEden论坛上一个推荐的方法就是在类中定义一个指向Signal处理函数的指针就可以,但是却破坏了封装,很令人沮丧。如果大家有这方面的应用,还是建议用线程做好了,但是也面临者同样的问题,即函数类型不匹配的情况。但是情况却要比Signal好的多,因为线程可以用cond和mutex来协调程序的执行,而且不用再去申请共享内存就可以达到共享的目的。
我这里有一个例子,大家可以参考一下,错误之处,请指正
LogPool.h
[code:1]
#ifndef LOGPOOL_H
#define LOGPOOL_H

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>


#ifndef LOGPOOL_SIZE
        const short LOGPOOL_SIZE  = 16;
#endif

#ifndef LOGITEM_SIZE
        const short LOGITEM_SIZE = 128;
#endif
       
class LogPool
{
public:
        LogPool();
        //将收到的信息放置到BUF里面
        void PlaceLog(const char* pNewLog);
        //从BUF里面取出一条日志记录,将记录拷贝到pLogBuf里面
        void FetchLog(char *pLogBuf);
private:       
        char m_Pool[LOGPOOL_SIZE][LOGITEM_SIZE];        //存放的Log数据
       
        short m_FetchPos;                         //下一个取数据的位置
        short m_PlacePos;                        //下一个放置日志的位置
       
        pthread_mutex_t m_Lock;                //互斥锁       
        pthread_cond_t m_NotEmpty;        //不空的一个条件
        pthread_cond_t m_NotFull;        //不满的一个条件
};
#endif
[/code:1]

LogPool.cpp
[code:1]
#include <string.h>
#include <assert.h>
#include "LogPool.h"

LogPool::LogPool()
{
        pthread_mutex_init(&m_Lock, NULL);
        pthread_cond_init(&m_NotEmpty, NULL);
        pthread_cond_init(&m_NotFull, NULL);
        m_FetchPos = 0;
        m_PlacePos = 0;
}

//将收到的信息放置到BUF里面
void LogPool::PlaceLog(const char* pNewLog)
{
        assert(pNewLog);
        pthread_mutex_lock(&m_Lock);
       
        while((m_PlacePos + 1) % LOGPOOL_SIZE == m_FetchPos)
        {
                pthread_cond_wait(&m_NotFull, &m_Lock);
        }
       
        memset(m_Pool[m_PlacePos], 0, LOGITEM_SIZE);
        strcpy(m_Pool[m_PlacePos], pNewLog);
        m_PlacePos = (m_PlacePos + 1) % LOGPOOL_SIZE;
       
        pthread_cond_signal(&m_NotEmpty);
        pthread_mutex_unlock(&m_Lock);
}

void LogPool::FetchLog(char *pLogBuf)
{
        pthread_mutex_lock(&m_Lock);
        while(m_PlacePos == m_FetchPos)
        {
                pthread_cond_wait(&m_NotEmpty, &m_Lock);
        }
       
        strcpy(pLogBuf, m_Pool[m_FetchPos]);
        m_FetchPos = (m_FetchPos + 1) % LOGPOOL_SIZE;
       
        pthread_cond_signal(&m_NotFull);
        pthread_mutex_unlock(&m_Lock);
}
[/code:1]

main.cpp
[code:1]
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>

#include "LogPool.h"

void *Producer(void* pLogPool)
{
        int n;
        char message[128];
        memset(message, 0, 128);
        for(n = 0; n < 50; n++)
        {
                sprintf(message, "Hello Thread %d Times--->", n);
                printf("%s\n", message);
                fflush(stdout);
                ((LogPool *)pLogPool)->PlaceLog(message);
                sleep(random() % 2);
        }
        return NULL;
}

void *Consumer(void *pLogPool)
{
        int tid = pthread_self();
        char message[128];
        memset(message, 0, 128);
       
        while(1)
        {
                //从Buf中取消息
                ((LogPool *)pLogPool)->FetchLog(message);
                //进行处理
                printf("Receive Message '%s' by %d\n", message, tid);
                sleep(2);
        }
        return NULL;
}


int main(int argc, char *argv[])
{
        pthread_t th_procedure, th_consumer1, th_consumer2, th_consumer3;
       
        LogPool newPool;
        LogPool *pPool = &newPool;
       
        pthread_create(&th_procedure, NULL, Producer, (void *)pPool);
        pthread_create(&th_consumer1, NULL, Consumer, (void *)pPool);
        pthread_create(&th_consumer2, NULL, Consumer, (void *)pPool);
        pthread_create(&th_consumer3, NULL, Consumer, (void *)pPool);
       
        pthread_join(th_procedure, NULL);
        pthread_join(th_consumer1, NULL);
        pthread_join(th_consumer2, NULL);
        pthread_join(th_consumer3, NULL);
        return 0;
}
[/code:1]
当然,又很多判断错误处理我没有加进去,请大家原谅

我发现在这里面讨论C语言的很多?是不是C++在Linux下面是不是没有太多的市场,还是控制台的程序大多都是用C写的?C很有优势吗?因为我写C程序的时候,感到很不方便,特别是读一些开源代码,好像很少能找到用C++写的程序
发表于 2004-4-23 17:37:40 | 显示全部楼层
能贴贴你上次那个贴子吗?感兴趣,不过自己找不到。
找到了(论坛"扯拐"中.............)
请恢复后斑主删除本贴(节约空间),谢谢!
回复

使用道具 举报

发表于 2004-4-23 19:30:45 | 显示全部楼层
在linux下C还不够方便吗?象你上面写的程序用C一样清晰简明。
回复

使用道具 举报

 楼主| 发表于 2004-4-26 14:59:34 | 显示全部楼层
如果只是实现上面的功能,用C当然是很简洁的,这个我绝对赞成。这个例子只是测试用的一个小例子,我实际做的东西要比上面实现的功能复杂的多。复杂度一大,用C++的优势就显出来的。我个人认为读C++的程序要比C的程序舒服的多,当然我并不是排斥用C,因为有众多的OpenSource都是用C写成的,用C++得很少见,而且国内很多软件公司都是改的OpenSouce。
回复

使用道具 举报

发表于 2004-4-27 22:30:56 | 显示全部楼层
做大项目C++是有很有优势,不过开源项目的特性(团队的成员水平)、unix系统与c的天然结合、C++的极度复杂性(原谅我这么认为,当我看的C++书越多,我越这么认为,可能是我太愚笨了)让C语言的项目比较多,不过,据统计(code reading 还是编程之道,我忘了),C++与C的项目数几乎差不多(8000多?只记得有个
楼主的代码我看了,比较好的封装,不过,我觉得这是一个以消息驱动为主体的程序框架,与类unix的信号(异步事件处理)机制似乎不同?就是说,我认为这个框架不能用在信号的类封装里。不对之处,多多探讨啊。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 11:54 , Processed in 0.043073 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表