c-在一个应用程序中注册回调,以便在另一个应用中检索


gcc 4.6.0 c89

我有客户端服务器应用程序的类型。服务器在事件循环中等待来自客户端的事件的一些代码。

这不是将使用UDP/TCP套接字的客户端服务器。但是客户端和服务器将在同一台linux机器上运行。我想这就像app1与运行在同一服务器上的app2对话。

我知道我需要使用函数指针(回调),并且我需要在客户端应用程序中注册回调。服务器将等待来自客户端的事件,并相应地采取行动。

所以我在服务器上的设计是这样的:

while(running) {
switch(event) {
case START_SDL:
/* DO something */
break;
case DELETE_EDL:
/* Do something */
break;
}
}

这样,服务器就在循环中运行,等待从客户端接收事件。然而,我不知道如何开始。

非常感谢您的任何建议,

您应该使用一个工作线程来等待来自主线程的事件并对其进行处理。这是一个很长的答案,为了避免时间过长,我将省略错误检查,尽管这违反了第六条戒律。

任务结构和队列

制作一个指定任务的结构。我将使用通用的get_taskpush_task函数在一个真实的例子中,应该使用tasks的线程安全队列,但这会使答案变得毫无用处。我只是从我手头的旧程序中勾画出来的。

struct task {
/* function callback */
void (*fun)(void *);
/* parameter to pass to callback */
void *arg;
};

同步

使用互斥锁来保护任务队列,使用信号量来表示有工作要做。请看我上面用粗体写的内容。

/* this has to be initialized in main */
sem_t sem;
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

工人功能

worker函数只是等待并在收到通知时执行任务。

static void *worker(void *arg)
{
struct task t;
/* detach */
pthread_detach(pthread_self());
/* loop forever */
while (1) {
/* block until we have work to do */
sem_wait(&sem);
/* we've got work to do */
pthread_mutex_lock(&mtx);
/* get the task */
t = get_task();
pthread_mutex_unlock(&mtx);
/* we are safe now, nobody can touch t */
/* execute the callback - here is your function pointer*/
(*t.fun)(t.arg);
}
return NULL;
}

主要功能

主要功能的作用是初始化内容和推送任务。

pthread_t t1;
/* initialize unnamed semaphore */
sem_init(&sem, 0, 0);
/* start worker thread */
if (0 != pthread_create(&t1, NULL, worker, NULL)) {
perror("pthread_create");
exit(1);
}

推送任务

此时,工作线程正在等待可以从main推送的任务。

pthread_mutex_lock(&mtx);
push_task(my_task);
pthread_mutex_unlock(&mtx);

这个服务器怎么会知道客户端正在触发事件?这是由你决定的,有很多方法可以在Unix上进行IPC。我的建议是使用消息队列

服务器消息队列示例

#define MSGSIZE 1024
int main()
{
mqd_t mq;
struct mq_attr attr;
char message[MSGSIZE];
int read_bytes;
attr.mq_maxmsg = 10;
attr.mq_msgsize = MSGSIZE;
mq = mq_open("/queue", O_RDWR | O_CREAT, 0700, &attr);
if ((mqd_t)-1 == mq) {
perror("mq_open");
exit(1);
}
while (1) {
/* get message from queue */
read_bytes = mq_receive(mq, message, MSGSIZE, NULL);
if (-1 == read_bytes) {
perror("mq_receive");
exit(1);
}
/* do what you wish with the message */
}
}

因此,在"为所欲为"部分,您可以调用解释事件类型并将其推送给工作者。从客户那里发送消息非常相似,所以我不会发布(如果你真的做不到,就问问)。

这些都只是一个大谜题中的(可能是破碎的)部分。你的任务是把它们组装成你正在建造的任何东西。

除非这是一项家庭作业,否则我建议使用许多可用的IPC库之一:

  • libassuan是非常轻量级和安全的,用于GnuPG组件之间
  • libdbus,Unix上的标准(桌面)IPC库
  • 任何数量的CORBA实现,例如MICO、TAO或omniORB
  • 任何数量的MPI实现,例如LAM(现在的OpenMPI)

在*nix上,

我建议使用select()或poll(),或者,如果你真的想的话,使用线程。

在窗口上,这是一个很好的指导Winsock API。我对Windows编程不是很有经验,但据我所知,Winsocks是低级别套接字IO的方法。

编辑;

我看到了评论,很明显你在使用Linux和线程。

首先,让我告诉你,线程不容易使用,因为你必须防止两个线程同时访问相同的数据,等等。

然而,这绝对是可能的。

如果你只是作为一个学习练习来做这件事,我建议你制作一个集中的数据集(所有线程都可以访问),它是互斥的,并为每个连接创建一个线程。

如果你在生产环境中,事情就不那么容易了。首先,我建议你读一下这篇文章。然后,考虑线程池。基本上,您从一堆线程(即池)开始,然后边执行边完成任务。在维基百科上可以找到一个非常好的描述。而且,我链接的PDF也显示了其他方式。

如果你看完这些之后不想使用线程,我仍然建议选择()和poll(),它们非常容易使用。

考虑到您有基本的pthread工作,实际的代码本身应该非常简单。

一个服务器进程和一个客户端进程。。看起来像生产者和消费者的关系。这用管子很容易处理。

bash# client | server 

客户端将事件写入stdout,服务器从stdin读取。如果您需要不止一个客户端,请参阅mmutz的答案

我对C或C++了解不多,但在java中,我会使用Future Task和非阻塞IO的组合来解决这个问题。请看一看,只是想找个主意。

相关内容

  • 没有找到相关文章

最新更新