QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 958|回复: 5

C++中给进程发信号的问题

[复制链接]
发表于 2004-4-22 11:50:40 | 显示全部楼层 |阅读模式
我知道在C中如果要给另外一个进程发送信号只要设置signal函数即可
[code:1]
void sig_usr(int);

int main()
{
     if(signal(SIGUSR1, sig_usr) == SIG_ERR)
     {
             //错误处理
     }
      ...
}

void sig_usr(int signo)
{
     if(signo = SIGUSR1)
     {
          ..
     }
}
[/code:1]

可是在C++中,我该怎么处理呢?

因为如果是一个用一个对象的一个方法作为处理函数的话,是不是把处理函数sig_usr()变为对象的那个方法就可以了,如下:
我以前这样试过,代码如下,好像不行,各位有确切的答案吗?谢谢
Observer.h

[code:1]

#ifndef OBSERVER_H
#define OBSERVER_H

class Observer
{
public:
        void Running();
        void ReceiveSignal(int signo);
};

#endif
[/code:1]

Observer.cpp

[code:1]
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

#include "Observer.h"

void Observer::ReceiveSignal(int signo)
{
        if(signo == SIGUSR1)
        {
                cout<<"Receive Signal"<<endl;
        }
        return;
}

void Observer::Running()
{
        if(signal(SIGUSR1, ReceiveSignal) == SIG_ERR)
        {
                cout<<"Error: signal()"<<endl;
                exit(0);
        }
       
        while(1)
        {
                sleep(1);
        }
}
[/code:1]

我编译的时候给出了下面的错误
[code:1]
...
Observer.cpp: In member function `void Observer::Running()':
//ee/home/wdq/project/CPlusSignal/Observer.cpp(18): no matches converting function `ReceiveSignal' to type `void
   (*)(int)'
//ee/home/wdq/project/CPlusSignal/Observer.cpp(8): candidates are: void Observer::ReceiveSignal(int)
...
[/code:1]

在C++里面要实现这样的功能应该这样做吗?[/code]
发表于 2004-4-22 16:05:41 | 显示全部楼层
说明你没有与这个回调函数原型匹配的实现。在类中的函数有一个隐含的this指针,所以你的那个回调会被编译器改成ReceiveSignal(&对象名,...)即加了一个this指针(C++PRIMER P523)。
要在Gtk中用C++见http://www.gtk.org/tutorial/ch-introduction.html
回复

使用道具 举报

发表于 2004-4-22 19:30:51 | 显示全部楼层

同问,我遇到了同样的难题!

如果用类中的static实现handle,也太局限性了吧!
  拿到没有其他办法了吗?
  前辈们指点一下吧!
回复

使用道具 举报

 楼主| 发表于 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]
回复

使用道具 举报

 楼主| 发表于 2004-4-23 16:44:52 | 显示全部楼层
请斑竹把下面的帖子删除,当时贴的时候显示贴不上去,但是谁知道后来又贴上了
回复

使用道具 举报

 楼主| 发表于 2004-4-23 16:46:39 | 显示全部楼层
请斑竹把下面的帖子删除,当时贴的时候显示贴不上去,但是谁知道后来又贴上了
回复

使用道具 举报

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

本版积分规则

GMT+8, 2024-11-8 10:55 , Processed in 0.072429 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

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