简体   繁体   English

如何应对比赛条件

[英]How to deal with a race condition

I'm pretty new to web development. 我是Web开发的新手。 From what I've read on race conditions I thought with node or JS they wouldn't be possible because of it being single threaded, but I see that is.. I guess wrong. 从我所阅读的关于竞争条件的内容中,我认为使用Node或JS不可能,因为它们是单线程的,但我认为那是..我猜错了。 With this little example can someone explain how it would work. 有了这个小例子,有人可以解释它是如何工作的。

If there is a bank account with $1000 dollars in it and two people charge the account at the exact same second hitting the server at the exact same time. 如果有一个有$ 1000美元的银行帐户,并且两个人在完全相同的第二个相同的时间击中服务器,则对该帐户收费。 First person charges $600 and the second person charges $200. 第一人称收费600美元,第二人称收费200美元。

The first charge would do $1000 - $600 leaving the balance at $400. 第一笔费用为$ 1000-$ 600,余额为$ 400。 But since the second charge hit at the exact same time it would do $1000 - $200 leaving the balance at $800. 但是,由于第二次收费的时间恰好相同,所以它将执行$ 1000-$ 200,而余额为$ 800。 When obviously the balance should now be $200. 显然,此时的余额应为200美元。

From my understanding that would cause a race condition, no? 据我了解,这会导致比赛状况,不是吗? How would you set this up to avoid this problem? 您将如何设置它以避免此问题? I don't need exact code just maybe someone to explain this to me, or pseudo code. 我不需要确切的代码,只是有人可以向我解释这一点,或者是伪代码。

Thanks in advance. 提前致谢。

EDIT: I'll edit it for how the code would be set up initially causing the race condition. 编辑:我将对其进行编辑,以了解最初如何设置代码以导致出现竞争状况。

Like the post below said. 就像下面的帖子所说。 The code would be set up so that when the account is hit it would subtract the amount and give the new balance. 将设置代码,以便在打到帐户时将减去金额并提供新的余额。 Obviously that would cause the race condition. 显然,这将导致比赛条件。

Your example cannot be answered specifically without seeing the exact code being used as there are safe ways to write that code and unsafe ways to write it. 在没有看到确切的代码的情况下,无法具体回答您的示例,因为存在编写该代码的安全方法和编写该代码的不安全方法。

node.js is single threaded, but as soon as a request makes an async call, then other requests can run while that async request is being carried out. node.js是单线程的,但是一旦一个请求进行了异步调用,那么在执行该异步请求时其他请求就可以运行。 Thus, you can have multiple requests in flight at the same time. 因此,您可以同时执行多个请求。 Whether or not this causes a "race condition" depends entirely upon how you write your code and, in your particular case, how you access the database. 这是否导致“竞赛条件”完全取决于您如何编写代码以及在特定情况下访问数据库的方式。

If you write code like this (pseudo-code): 如果您编写这样的代码(伪代码):

 get total from database
 subtract from total
 write new total to database

And, the calls to the database are asynchronous (which they likely are), then you definitely have a race condition because in between the time you get the total and write the total, other requests could be attempting to access the same total value and attempting to modify it and one request will either not have the latest total value or the two will stomp on each other's results (one overwriting the other). 而且,对数据库的调用是异步的(很可能是异步的),因此您肯定有一个竞争条件,因为在获得总数和写入总数之间,其他请求可能试图访问相同的总数并尝试修改它,一个请求要么没有最新的总价值,要么两个都占用了对方的结果(一个覆盖另一个)。

If, on the other hand, you have a database that can do an atomic modification of the total value in the database as in: 另一方面,如果您有一个数据库,可以对数据库中的总值进行原子修改,如下所示:

subtract x from total in database

Then, you will be protected from that particular race condition. 然后,您将受到保护,免受特定种族条件的影响。


Because node.js is single threaded, it is not as complicated to write safe code in node.js as it is in a multi-threaded web server. 由于node.js是单线程的,因此在node.js中编写安全代码并不像在多线程Web服务器中那样复杂。 This is because there is only one path of Javascript executing at the same time. 这是因为同时执行Javascript的路径只有一条。 So, until you make some sort of asynchronous I/O call, no other request will literally be running at the same time. 因此,除非您进行某种异步I / O调用,否则其他请求实际上不会同时运行。 This makes accessing shared variables in your node.js app massively simpler than in a true multi-threaded web server environment where any access to a shared variable must be protected by a mutex (or something similar). 这比在真正的多线程Web服务器环境中访问node.js应用程序中的共享变量要简单得多,在真正的多线程Web服务器环境中,对共享变量的任何访问都必须由互斥锁(或类似的东西)保护。 But, as soon as you make an async call, you must be aware that at that point in time, other requests can run. 但是,一旦您进行异步调用,就必须意识到在那个时间点,其他请求可以运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM