libevent是否同时处理两个事件,这是否意味着我需要互斥锁?

huangapple go评论45阅读模式
英文:

Does libevent process two events concurrently which means I need mutex?

问题

我正在尝试使用libevent库。我定义了一些事件,但在我的代码中没有创建任何线程。

我的问题是,如果几个事件可以访问/修改同一个共享结构体,我是否需要一个互斥锁来锁定关键部分,以避免竞态条件?或者libevent是否设计成事件只能按顺序执行,而不会并发执行?

备注:

  1. 当然,这个问题只涉及我的事件本身不会生成新线程的情况。
  2. 我的担忧主要来自我对JavaScript的经验:JavaScript也使用事件循环设计,但即使只有一个线程,我们仍然可能损坏数据。原因是,据我了解,JavaScript可以“暂停”一个事件的执行并启动第二个事件,然后恢复暂停的事件。如果暂停恰好发生在修改共享对象的代码行之间,它可能会损坏我的对象。
  3. 已经阅读了文档,但没有找到我正在寻找的明确答案。
英文:

I am experimenting with the libevent library. I defined a few events and I do not create any threads in my code.

My question is, if a few events can access/modify the same shared struct, do I need a mutex to lock the critical section to avoid race condition? Or is libevent designed in a way that events can only be executed consecutively, never concurrently?

Notes:

  1. But of course the question is only about the case in which my events do not spawn new threads themselves
  2. My concern is mainly from my experience with JavaScript: JavaScript uses event loop design as well but we can still corrupt data even if there is only one thread. The reason is that JavaScript can, as I understand, "pause" the execution of one event and start a second event, then resume the paused event. If the pause happens right between lines that modify a shared object, it can corrupt my object.
  3. RTFM already but does not find the definite answer I am looking for

答案1

得分: 4

Libevent 默认设计为单线程。它提供了一种异步事件通知机制,这意味着它以非阻塞、事件驱动的方式处理事件。如果您有多个事件可能会修改相同的数据结构,并且没有创建任何线程,通常不需要使用互斥锁来避免竞态条件,因为这些事件不会同时执行,而是一个接着一个执行。

然而,重要的是要知道 libevent 支持多线程模式,可以创建多个线程并同时处理事件。如果您要使用这种模式,确实需要在访问共享数据时进行适当的同步(例如使用互斥锁)以避免竞态条件。

进一步说明,在 libevent 的默认单线程事件驱动模式中,有一个事件循环按触发的顺序逐个处理事件。在事件处理程序运行时,不会处理其他事件。这有效地防止了竞态条件,无需额外的同步。

请记住,只要您的事件不会自己创建新线程,并且您在其默认的单线程模式下使用 libevent,这一点仍然成立。如果您的应用程序或库已配置为使用多线程,则需要确保适当的同步。

英文:

Libevent is designed to be single-threaded by default. It provides a mechanism for asynchronous event notification, which means it handles the events in a non-blocking, event-driven way. If you have multiple events that can potentially modify the same data structure and you are not creating any threads yourself, you generally don't need to use a mutex to avoid race conditions because these events will not be executed concurrently, but rather one after another.

However, it's important to be aware that libevent does support multi-threaded mode, where multiple threads can be created and events handled concurrently. If you were to use this mode, you would indeed need to ensure proper synchronization (like using mutexes) when accessing shared data to avoid race conditions.

To further clarify, in a single-threaded event-driven model like the default mode in libevent, there is a single event loop that processes events one at a time in the order they are triggered. While an event handler is running, no other event can be processed. This effectively prevents race conditions without the need for additional synchronization.

Remember that this holds true as long as your events don't spawn new threads themselves and you're using libevent in its default, single-threaded mode. If your application or the library is configured to use multiple threads, then you would need to ensure proper synchronization.

答案2

得分: 0

我的担忧主要来自我对JavaScript的经验:JavaScript也使用事件循环设计,但即使只有一个线程,我们仍然可以损坏数据。原因是JavaScript可以在我理解的情况下“暂停”一个事件的执行并启动第二个事件,然后恢复已暂停的事件。

你描述的情况在事件循环中不太典型。它们通常依赖于一个事件队列,一个接一个地处理。

而你描述的情况在C的操作模型中不太支持。C定义线程的工作被抢占以在同一线程中执行不同的工作的唯一方式是线程接收导致运行信号处理程序函数的信号。但信号处理程序不适用于执行任意处理,因此虽然libevent可能会使用信号处理程序来排队事件,但不太可能在信号处理程序内调用相关的回调函数。

那么请放心。只要你只有一个线程,你的事件回调不会被抢占以运行其他事件回调,也不会同时运行两个回调函数。

英文:

> My concern is mainly from my experience with JavaScript: JavaScript uses event loop design as well but we can still corrupt data even if there is only one thread. The reason is that JavaScript can, as I understand, "pause" the execution of one event and start a second event, then resume the paused event.

What you describe is atypical of event loops. They usually rely on a queue of events, processed one after another.

And what you describe is not really supportable in C's model of operation. The only way C defines for a thread's work to be preempted to perform different work in the same thread is if the thread receives a signal that causes a signal handler function to run. But signal handlers are not suitable for performing arbitrary processing, so although it's conceivable that libevent might use a signal handler to enqueue events, it is not plausible that it would call associated callbacks within the signal handler.

Rest at ease, then. Provided that you have only one thread, your event callbacks will not be preempted to run other event callbacks, and no two callbacks can run concurrently.

huangapple
  • 本文由 发表于 2023年5月30日 10:01:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76361184.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定