|
楼主 |
发表于 2004-4-23 16:43:18
|
显示全部楼层
谢谢大家!用这个确实不大好做,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>
#include "LogItem.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] |
|