我在多线程环境中使用Redis,我有一个关于它如何操作的问题。我在我的c++应用程序中使用hiredis c库。
我的问题是:如果我在触发回调时使用异步模式,回调会在Redis客户端创建的另一个线程中处理吗?例如,创建调用的线程不会受到回调处理的影响吗?谢谢!
发布于 2016-02-16 16:39:47
Redis客户端不创建任何额外的clent线程,并在现有线程中工作。
Redis在另一个(主)进程中工作。您使用的redis API在本地进程中工作,并使用进程间通信来主进程。异步请求意味着进程或线程将任务放到另一个进程或线程中,之后可以执行任何其他任务或等待事件。一段时间后,异步回复到达您的应用程序,并可供使用。您的应用程序必须使用https://en.wikipedia.org/wiki/Event_loop或任何通过调用回调来通知您的异步管理系统来处理事件(在本例中为redis应答)。
异步体系结构意味着您运行事件循环,为每个事件调用回调处理程序。回调时,可以创建多个异步任务。一旦任务创建,当任务完成或发生错误时,回调事件处理程序就会被调用。可以将回调分配给启动应用程序或出现新的web连接。回调时可以创建redis任务,后续会调用result事件回调。当前线程中的所有内容。我н你有多个线程,合理地期望每个线程有一个事件循环。
Redis的单线程特性:http://redis.io/topics/latency#single-threaded-nature-of-redis
客户端套接字处于非阻塞状态,因为Redis使用多路复用和非阻塞I/O。http://redis.io/topics/clients这意味着您的客户端永远不会被阻塞。
Redis中的2.4线程只用于在后台执行一些缓慢的I/O操作,主要与磁盘I/O相关,但这并不能改变Redis使用单个线程服务所有请求的事实。
发布于 2018-05-03 20:47:53
当您调用redisAsyncHandlerRead()时,Hiredis调用回调。因此,回调是在用于调用redisAsyncHandlerRead()的任何线程上调用的。
我相信一个最小的Redis异步示例,在Linux-ish C中,应该是这样的(为了清楚起见,删除了错误检查):
#include "async.h"
#include <unistd.h>
#include <stdio.h>
void myRedisCallback(redisAsyncContext *c, void *typeless_reply, void *priv_data) {
redisReply *r = (redisReply *)typeless_reply;
if (r->type == REDIS_REPLY_STRING)
printf("foo is %s\n", r->str);
}
int main() {
redisAsyncContext *c = redisAsyncConnect("localhost", 6379);
redisAsyncCommand(c, myRedisCallback, NULL, "GET foo");
for (int i = 0; i < 100; i++) {
redisAsyncHandleWrite(c); // This sends the command.
redisAsyncHandleRead(c); // This calls the callback if the reply has been received.
usleep(10000); // A real app would do something here.
}
return 0;
}发布于 2021-01-19 19:57:34
redisAsyncHandleRead()或redisAsyncHandleWrite()将调用您之前注册的任何回调函数。它不会在每次查看时“开火”。文档和async.h文件都没有明确说明如何获取文件描述符(ac->c.fd)来实现epoll事件循环:
#define MAX_EVENTS 10
int epfd;
if((epfd = epoll_create1(0)) == -1) {
// handle error
};
redisAsyncContext *ac = redisAsyncConnect("127.0.0.1", 6379);
if(epoll_ctl(epfd, EPOLL_CTL_ADD, ac->c.fd, &(struct epoll_event) { .events = EPOLLIN | EPOLLOUT | EPOLLET }) == -1) {
// handle error
}
int nfds;
struct epoll_event events[MAX_EVENTS];
for(;;) {
if((nfds = epoll_wait(epfd, events, MAX_EVENTS, -1) == -1) {
// handle error
}
for(int i = 0; i < nfds; i++) {
if(events[i].events & EPOLLIN) redisAsyncHandleRead(ac);
if(events[i].events & EPOLLOUT) redisAsyncHandleWrite(ac);
}
}https://stackoverflow.com/questions/35426726
复制相似问题