Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/448.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用Node.js中传入的函数初始化子进程 上下文_Javascript_Node.js_Concurrency_Parallel Processing_Child Process - Fatal编程技术网

Javascript 如何使用Node.js中传入的函数初始化子进程 上下文

Javascript 如何使用Node.js中传入的函数初始化子进程 上下文,javascript,node.js,concurrency,parallel-processing,child-process,Javascript,Node.js,Concurrency,Parallel Processing,Child Process,我正在构建一个使用该算法的通用程序。这个想法很简单,框架提供了算法的框架,包括四个主要步骤:选择、扩展、模拟和反向传播。用户只需插入四个简单(ish)游戏相关功能即可: 在游戏状态下接收并返回所有可能的合法移动的函数 接受游戏状态和动作并在应用动作后返回新游戏状态的函数 一种函数,用于接收游戏状态并确定游戏是否结束,并返回布尔and 一个函数,它接受一个状态和一个玩家ID,并根据玩家是赢了、输了还是平局返回一个值。这样,算法就可以运行并选择要执行的移动 我想做什么 我希望利用并行编程来增加算法的

我正在构建一个使用该算法的通用程序。这个想法很简单,框架提供了算法的框架,包括四个主要步骤:选择、扩展、模拟和反向传播。用户只需插入四个简单(ish)游戏相关功能即可:

  • 在游戏状态下接收并返回所有可能的合法移动的函数
  • 接受游戏状态和动作并在应用动作后返回新游戏状态的函数
  • 一种函数,用于接收游戏状态并确定游戏是否结束,并返回布尔and
  • 一个函数,它接受一个状态和一个玩家ID,并根据玩家是赢了、输了还是平局返回一个值。这样,算法就可以运行并选择要执行的移动
  • 我想做什么 我希望利用并行编程来增加算法的强度,并减少运行每个游戏回合所需的时间。我遇到的问题是,在NodeJS中使用子进程时,不能将函数传递给子进程,而我的框架完全是使用用户传递的函数构建的

    可能的解决办法 我已经看过了,但我不确定这是否适合我的需要。我不需要不断地通过消息将函数传递给子进程,我只需要在初始化框架时使用框架用户传入的函数对其进行初始化

    我想了一种方法,但它似乎太不雅观了,除了可能不是最安全的,我发现自己在寻找其他解决方案。当用户初始化框架并将其四个函数传递给它时,我可以获得一个脚本,将这些函数写入一个新的js文件(我们称之为
    my funcs.js
    ),该文件类似于:

    const func1 = {... function implementation...}
    const func2 = {... function implementation...}
    const func3 = {... function implementation...}
    const func4 = {... function implementation...}
    
    module.exports = {func1, func2, func3, func4}
    
    然后,在子进程工作者文件中,我想我必须找到一种方法来延迟加载require
    myfuncs.js
    。或者我不会,我想这取决于Node.js如何以及何时将worker文件加载到内存中。这一切似乎都很复杂


    你能描述一下获得我想要的结果的其他方法吗?

    假设安全性不是问题,你可以这样做

    // Client side
    <input class="func1"> // For example user inputs '(gamestate)=>{return 1}'
    <input class="func2">
    <input class="func3">
    <input class="func4">
    
    <script>
      socket.on('syntax_error',function(err){alert(err)});
      submit_funcs_strs(){
        // Get function strings from user input and then put into array
        socket.emit('functions',[document.getElementById('func1').value,document.getElementById('func2').value,...
      }
    </script>
    
    // Server side
    
    // Socket listener is async
    socket.on('functions',(funcs_strs)=>{
      let funcs = []
      for (let i = 0; i < funcs_str.length;i++){
        try {
            funcs.push(eval(funcs_strs)); 
        } catch (e) {
            if (e instanceof SyntaxError) {
                socket.emit('syntax_error',e.message);
                return;
            }
        } 
    
      }
      // Run algorithm here
    }
    
    //客户端
    //例如,用户输入“(游戏状态)=>{return 1}”
    on('syntax_error',function(err){alert(err)});
    提交(功能){
    //从用户输入中获取函数字符串,然后放入数组
    emit('functions',[document.getElementById('func1')。value,document.getElementById('func2')。value,。。。
    }
    //服务器端
    //套接字侦听器是异步的
    socket.on('函数',(函数)=>{
    设funcs=[]
    for(设i=0;i
    子进程
    与其说是运行用户函数,不如说是启动新线程来执行文件或进程

    Node本质上是一个单线程系统,因此对于I/O绑定的东西,Node事件循环非常擅长在请求之间切换,使每个请求都更进一步。请参阅

    看起来您正在尝试让JavaScript同时运行多个线程。简短的回答:不能……或者更确切地说,这真的很难。请参阅

    那么我们该怎么做呢?你说得对:
    child\u process.fork()

    我设想了一个数据存储,您可以在其中获取
    userFn.ToString()
    并将其保存到队列中。然后分叉进程,让它拾取队列中下一个未处理的内容,标记它这样做了。然后将结果写入另一个队列,并使用此“GUI”然后,线程对该队列进行轮询,将计算结果返回给用户。此时,您得到了多线程…和竞争条件

    另一个想法是:创建一个REST服务,它接受
    userFn.ToString()
    内容并
    exec
    s它。然后在这个模块中,调用另一个“线程”(服务),等待结果并返回它们


    安全性:是的,我们只是把它扔出了窗口。不管你是直接执行用户的函数,调用
    child\u process#fork
    来执行,还是通过服务填充,你都信任不受信任的代码。遗憾的是,真的没有办法解决这个问题。

    你信任这些函数吗?它们能做任何他们想做的事情吗?或者你想做什么要在沙盒环境中运行它们?我信任它们。另外,我已经进行了验证,可以最大限度地减少有人通过有害函数的可能性。那么,您已经拥有的是最好的方法。我将创建一个共享文件夹,动态代码转到
    file-.js
    ,然后使用
    process.send({file:.js})
    ,代码将需要它并使用它。但您需要注意的是,启动的CPU不应超过(2*CPU+1)进程,否则好处可能不多。另外,您从一开始就创建了所有工作进程,并继续向它们发送工作。将代码发送到eval不会带来太多的发送,在这种情况下,文件会更好case@Tarun拉尔瓦尼:我现在对这个问题很感兴趣。如果你愿意,你可以写一份正式的答复等待您的评论。当然会根据您的回购协议制定答案