.= 'tag.htm'; break; case 'flag': $pre .= $default_pre .= 'flag.htm'; break; case 'my': $pre .= $default_pre .= 'my.htm'; break; case 'my_password': $pre .= $default_pre .= 'my_password.htm'; break; case 'my_bind': $pre .= $default_pre .= 'my_bind.htm'; break; case 'my_avatar': $pre .= $default_pre .= 'my_avatar.htm'; break; case 'home_article': $pre .= $default_pre .= 'home_article.htm'; break; case 'home_comment': $pre .= $default_pre .= 'home_comment.htm'; break; case 'user': $pre .= $default_pre .= 'user.htm'; break; case 'user_login': $pre .= $default_pre .= 'user_login.htm'; break; case 'user_create': $pre .= $default_pre .= 'user_create.htm'; break; case 'user_resetpw': $pre .= $default_pre .= 'user_resetpw.htm'; break; case 'user_resetpw_complete': $pre .= $default_pre .= 'user_resetpw_complete.htm'; break; case 'user_comment': $pre .= $default_pre .= 'user_comment.htm'; break; case 'single_page': $pre .= $default_pre .= 'single_page.htm'; break; case 'search': $pre .= $default_pre .= 'search.htm'; break; case 'operate_sticky': $pre .= $default_pre .= 'operate_sticky.htm'; break; case 'operate_close': $pre .= $default_pre .= 'operate_close.htm'; break; case 'operate_delete': $pre .= $default_pre .= 'operate_delete.htm'; break; case 'operate_move': $pre .= $default_pre .= 'operate_move.htm'; break; case '404': $pre .= $default_pre .= '404.htm'; break; case 'read_404': $pre .= $default_pre .= 'read_404.htm'; break; case 'list_404': $pre .= $default_pre .= 'list_404.htm'; break; default: $pre .= $default_pre .= theme_mode_pre(); break; } if ($config['theme']) { $conffile = APP_PATH . 'view/template/' . $config['theme'] . '/conf.json'; $json = is_file($conffile) ? xn_json_decode(file_get_contents($conffile)) : array(); } !empty($json['installed']) and $path_file = APP_PATH . 'view/template/' . $config['theme'] . '/htm/' . ($id ? $id . '_' : '') . $pre; (empty($path_file) || !is_file($path_file)) and $path_file = APP_PATH . 'view/template/' . $config['theme'] . '/htm/' . $pre; if (!empty($config['theme_child']) && is_array($config['theme_child'])) { foreach ($config['theme_child'] as $theme) { if (empty($theme) || is_array($theme)) continue; $path_file = APP_PATH . 'view/template/' . $theme . '/htm/' . ($id ? $id . '_' : '') . $pre; !is_file($path_file) and $path_file = APP_PATH . 'view/template/' . $theme . '/htm/' . $pre; } } !is_file($path_file) and $path_file = APP_PATH . ($dir ? 'plugin/' . $dir . '/view/htm/' : 'view/htm/') . $default_pre; return $path_file; } function theme_mode_pre($type = 0) { global $config; $mode = $config['setting']['website_mode']; $pre = ''; if (1 == $mode) { $pre .= 2 == $type ? 'portal_category.htm' : 'portal.htm'; } elseif (2 == $mode) { $pre .= 2 == $type ? 'flat_category.htm' : 'flat.htm'; } else { $pre .= 2 == $type ? 'index_category.htm' : 'index.htm'; } return $pre; } ?>multithreading - Javascript thread-handling and race-conditions - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

multithreading - Javascript thread-handling and race-conditions - Stack Overflow

programmeradmin1浏览0评论

Lets asume I have a code like the following:

var shared = 100;
function workWithIt(){
    shared += 100;
}

setTimeout(workWithIt, 500);
setTimeout(workWithIt, 500);

Ideally, this piece of code should add 200 to the variable shared, which is 300 afterwards.

But, as I know from c, there can be some implications, if the operation += is split into multiple mands.

Lets say, that this is the execution-order of the function:

setTimeout() --> create Thread A
setTimeout() --> create Thread B
wait 500ms

      **Thread A**              |        **Thread B**
--------------------------------+---------------------------------
var tmpA = shared;  //100       |
                                |   var tmpB = shared; //100
                                |   tmpB = tmpB+100;   //tmpB=200
                                |   shared = tmpB;
tmpA = tmpA+100;    //tmpA=200  |
shared = tmpA;                  |

In this case, shared has now the value 200.

This can happen in many programming-languages like c, c++, java, c#, ... - but can it also happen in Javascript?

Or more generally speaking: How does Javascript handle its threads, when does it switch between threads, and are there built-in methods, that can be used for handling race-conditions?

Lets asume I have a code like the following:

var shared = 100;
function workWithIt(){
    shared += 100;
}

setTimeout(workWithIt, 500);
setTimeout(workWithIt, 500);

Ideally, this piece of code should add 200 to the variable shared, which is 300 afterwards.

But, as I know from c, there can be some implications, if the operation += is split into multiple mands.

Lets say, that this is the execution-order of the function:

setTimeout() --> create Thread A
setTimeout() --> create Thread B
wait 500ms

      **Thread A**              |        **Thread B**
--------------------------------+---------------------------------
var tmpA = shared;  //100       |
                                |   var tmpB = shared; //100
                                |   tmpB = tmpB+100;   //tmpB=200
                                |   shared = tmpB;
tmpA = tmpA+100;    //tmpA=200  |
shared = tmpA;                  |

In this case, shared has now the value 200.

This can happen in many programming-languages like c, c++, java, c#, ... - but can it also happen in Javascript?

Or more generally speaking: How does Javascript handle its threads, when does it switch between threads, and are there built-in methods, that can be used for handling race-conditions?

Share Improve this question edited Jan 30, 2014 at 22:26 noseratio 61.7k36 gold badges223 silver badges500 bronze badges asked Jan 30, 2014 at 21:02 majamaja 18.1k18 gold badges84 silver badges127 bronze badges 6
  • 3 JavaScript is single-threaded. – Pointy Commented Jan 30, 2014 at 21:04
  • But you can have several execution-lines in parallel, and the browser switches between them. Even if it happens within the same thread, the results are the same. – maja Commented Jan 30, 2014 at 21:06
  • 2 It's not "switching between them." Timers are like event generators, and the timer function is run to pletion before the next event (or timer) is processed. In your example, one function or the other will always run to pletion before the other starts. – Pointy Commented Jan 30, 2014 at 21:07
  • 1 Yes. The alert() function itself is an exception: while waiting for the user to dismiss the alert, browsers allow some event handlers to run (I can't recall exactly which ones). But running JavaScript code doesn't get interrupted by the browser - that's why pute-intensive code (or an infinite loop) can cause the browser to pop up a dialog asking if the user wants to terminate the running code. – Pointy Commented Jan 30, 2014 at 21:24
  • 1 Here is another good StackOverflow question. – Pointy Commented Jan 30, 2014 at 21:26
 |  Show 1 more ment

2 Answers 2

Reset to default 6

JavaScript code has a single explicit thread of execution. The scenario you've described will never take place in JavaScript. A timer callback is just another kind of event, and all events are serialized for sequential execution by the same core event loop of the browser UI thread.

Thus, two timer events cannot be processed concurrently, one callback will happen after another.

You still can have real concurrency in JavaScript by means of Web Workers. However, a web worker cannot share any objects with another web worker or the main thread. Instead, web workers serialize their state objects with JSON, and exchange messages with postMessage. So, your scenario is still impossible.

However, consider another case:

var shared = 100;

function workWithIt1(){
    shared += 100;
}

function workWithIt2(){
    shared = shared/2;
}

setTimeout(workWithIt1, 500);
setTimeout(workWithIt2, 500);

Will shared be 150 or 100, once both timeouts have been fired? It probably will be 100, because the workWithIt1 timeout was queued first. However, I would not rely upon this fact though, because both timers have the same timeout value of 500, and implementation of timers might be browser-specific. You may want to avoid side effects like that in your code.

AFAIK, there is no multithreading in JS. I changed your example a bit to try to understand what you mean.

var shared = 100;
function workWithIt(a){
    shared += a||100;
    console.log(shared);
}

setTimeout(function(){workWithIt(5);}, 500);
setTimeout(function(){workWithIt(10);}, 500);
console.log(shared);

With this code, the result is always (in my testing):

100
105
110

This indicates to me that there is no chaotic or random or even interesting process here. There are certain possibilities to create racing conditions with JS in the browser, but your timing example is not that. Racing requires only a breakdown in predictability of execution order. Maybe if you change your delay from 500 to Math.floor(500 * Math.random()) you would have a racing condition.

发布评论

评论列表(0)

  1. 暂无评论