sogou/workflow

为什么msgquque要自己实现一个?

Lisprez opened this issue · 11 comments

  • 我是一个技术非常初级的人,所以问的问题有点初级,请见谅.
  • 我看到实现是用的单链表, 为什么要自己实现一个呢? 用标准库中的List存在哪些问题呢?
    或者说这样做的考量主要是什么呢?
void msgqueue_put(void *msg, msgqueue_t *queue)
{
	void **link = (void **)((char *)msg + queue->linkoff);

	*link = NULL;
	pthread_mutex_lock(&queue->put_mutex);
	while (queue->msg_cnt > queue->msg_max - 1 && !queue->nonblock)
		pthread_cond_wait(&queue->put_cond, &queue->put_mutex);

	*queue->put_tail = link;
	queue->put_tail = link;
	queue->msg_cnt++;
	pthread_mutex_unlock(&queue->put_mutex);
	pthread_cond_signal(&queue->get_cond);
}

上面这个函数中的
*link = NULL;
这一句怎么能执行呢, link这个时候经过+linkoff, 不是已经偏移到了msg的边缘了吗?
不知道我哪里没有理解对, 谢谢

我们的原则是能C就不C++,这样别的C项目还能复用这个模块呢。而且kernel目录也不会使用STL的东西。
msg头部偏移linkoff字节,是链表指针的位置。使用者需要留好空间。这样我们就无需再malloc和free了。

借地提出个2个疑问:
1)*queue->put_tail = link;
queue->put_tail = link;
这里设置存放指针的位置,为什么要设置两次?第一句和第二句我理解是一样的效果啊?
2)linkoff字段我理解是不同平台指针类型占用的空间大小是吧?

1、相当于:

queue->put_tail->next = link;
queue->put_tail = link;

好理解吧?
2、不是。是一个偏移量。多少都可以。

1、相当于:

queue->put_tail->next = link;
queue->put_tail = link;

好理解吧? 2、不是。是一个偏移量。多少都可以。
所以这句应该这样理解是吧:*(queue->put_tail) = link;

1、相当于:

queue->put_tail->next = link;
queue->put_tail = link;

好理解吧? 2、不是。是一个偏移量。多少都可以。
所以这句应该这样理解是吧:*(queue->put_tail) = link;

这不是一样吗。"->"运算符的优先级比*高。

1、相当于:

queue->put_tail->next = link;
queue->put_tail = link;

好理解吧? 2、不是。是一个偏移量。多少都可以。
所以这句应该这样理解是吧:*(queue->put_tail) = link;

这不是一样吗。"->"运算符的优先级比*高。

是的o(╯□╰)o,谢谢

我们的原则是能C就不C++,这样别的C项目还能复用这个模块呢。而且kernel目录也不会使用STL的东西。 msg头部偏移linkoff字节,是链表指针的位置。使用者需要留好空间。这样我们就无需再malloc和free了。

被*link=NULL困扰好久,但是看到
void Communicator::callback(struct poller_result *res, void *context) { msgqueue_t *msgqueue = (msgqueue_t *)context; msgqueue_put(res, msgqueue); }
这么使用的,但是创建时:
this->msgqueue = msgqueue_create(16 * 1024, sizeof (struct poller_result));
你们在使用时,并没有预留空间吧?但是测试下来,并没有crash,非常奇怪。特此向大佬请教 @Barenboim

可以看一下poller.h,里面有个注释,struct poller_result结构后面是有空间的,因为内部的poller_node就是一个poller_result的扩展。

好的,非常感谢大佬 ^~^

这个没有任何区别,唤醒的时间是在解锁,也就是第82行,而不是signal/broadcast那句。signal之后,还在锁里呢,其它人是不能进入互斥区的。

被broadcast唤醒的人,也是依次进入互斥区,每一个人解锁,后一个才进去。

@Barenboim 嗯嗯 我刚刚也查了一些资料理解了,感谢大佬