V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  cuiweixie  ›  全部回复第 1 页 / 共 1 页
回复总数  7
2020-03-20 13:02:31 +08:00
回复了 RedisMasterNode 创建的主题 Redis 字节跳动一面复盘 & Redis 多线程 IO 模型
@RedisMasterNode master 处理的是它的 id=0 对应的 io_threads_list[0],这个 list 在 IOThreadMain 并不会处理,你可以看看看 IOThreadMain 启动的时候它没有启动对应 id=0 的 IOThreadMain
2020-03-20 11:36:43 +08:00
回复了 RedisMasterNode 创建的主题 Redis 字节跳动一面复盘 & Redis 多线程 IO 模型
@RedisMasterNode 加上你提供的注释我看懂了,为什么调了 startThreadedIO()也不会存在同时跑 main thread 跟 io thread 了,因为 io_threads_pending[id] == 0
2020-03-20 11:25:47 +08:00
回复了 RedisMasterNode 创建的主题 Redis 字节跳动一面复盘 & Redis 多线程 IO 模型
@RedisMasterNode 好的,这个注释被我忽略了,哈哈,这个 V2EX 的评论居然不支持富文本,贴代码的时候感觉好恶心
2020-03-20 11:15:50 +08:00
回复了 RedisMasterNode 创建的主题 Redis 字节跳动一面复盘 & Redis 多线程 IO 模型
如果是不存在 main thread 跟 io thread 同时执行,确实没 data race,但是没看明白为什么不会同时执行,比如
这里明显 start io thread,然后再往里面 add list node
int handleClientsWithPendingWritesUsingThreads(void) {
int processed = listLength(server.clients_pending_write);
if (processed == 0) return 0; /* Return ASAP if there are no clients. */

/* If we have just a few clients to serve, don't use I/O threads, but the
* boring synchronous code. */
if (stopThreadedIOIfNeeded()) {
return handleClientsWithPendingWrites();
}

/* Start threads if needed. */
if (!io_threads_active) startThreadedIO();//这里明显 start 了 io thread

if (tio_debug) printf("%d TOTAL WRITE pending clients\n", processed);

/* Distribute the clients across N different lists. */
listIter li;
listNode *ln;
listRewind(server.clients_pending_write,&li);
int item_id = 0;
while((ln = listNext(&li))) {
client *c = listNodeValue(ln);
c->flags &= ~CLIENT_PENDING_WRITE;
int target_id = item_id % server.io_threads_num;
listAddNodeTail(io_threads_list[target_id],c);
item_id++;
}
2020-03-20 10:54:08 +08:00
回复了 RedisMasterNode 创建的主题 Redis 字节跳动一面复盘 & Redis 多线程 IO 模型
@RedisMasterNode main 线程往 io_threads_list 写,io thread 读 io_threads_list ,比如
main thread 执行完下面标记的一行后,线程切换到了 io thread,io thread 遍历 io_threads_list[i],那么 node 的 prev,next 指针都没有被设置,这里就出现野指针了
list *listAddNodeTail(list *list, void *value)
{
listNode *node;

if ((node = zmalloc(sizeof(*node))) == NULL)
return NULL;
node->value = value;
if (list->len == 0) {
list->head = list->tail = node; // 这一行
node->prev = node->next = NULL;
} else {
node->prev = list->tail;
node->next = NULL;
list->tail->next = node;
list->tail = node;
}
list->len++;
return list;
}
2020-03-19 17:42:55 +08:00
回复了 RedisMasterNode 创建的主题 Redis 字节跳动一面复盘 & Redis 多线程 IO 模型
@RedisMasterNode 好的,多谢了
2020-03-19 16:13:15 +08:00
回复了 RedisMasterNode 创建的主题 Redis 字节跳动一面复盘 & Redis 多线程 IO 模型
@RedisMasterNode 读写 io_threads_list 的 data race 怎么解决的,没看到加锁,也不是原子操作
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2509 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 12ms · UTC 15:31 · PVG 23:31 · LAX 07:31 · JFK 10:31
Developed with CodeLauncher
♥ Do have faith in what you're doing.