gpt4 book ai didi

javascript - nodejs 中类似 c 的互斥量

转载 作者:太空宇宙 更新时间:2023-11-04 02:27:47 26 4
gpt4 key购买 nike

我正在尝试在 node.js 中实现类似 c 的等待和信号。我想到了二进制信号量或互斥量。请记住,我是 node.js 的新手,对 javascript 不是很熟练。

我的事情是:

  • 我有一个在服务器上运行的 python 交互进程。

  • 客户端向服务器发出 Ajax,服务器反过来通过在他的标准输入上写入来请求这个 python 进程。 http 响应对象保存在一个变量中。

  • 然后我拦截包含我的答案的标准输出,并将其发送到保留的响应对象中。

我想让这个“python 部分”成为原子的,这意味着:

  • 如果在 python 进程已经运行时收到另一个请求,请等待。否则请求将丢失。

  • 当标准输出触发时,发送信号以释放访问权限。

同样,与二进制信号量或互斥量锁和互斥量解锁中的 P 和 V 的行为相同。

所以如果你高级 nodejs 用户有什么建议?我查看了 npm,但除了类似 Promise 的互斥体之外什么也没有发现,我认为这不太适合我的情况。

也许我错了,有办法。无论如何,我期待阅读您的建议或解决方法。谢谢。

这是相关的示例代码。

route.js

var express = require('express');
var router = express.Router();
var pycaffe = require('./pycaffe');

var py = pycaffe.getInstance();

router.post('/getParams', function(req, res, next){
in_data = req.body.imgBase64;
py.queryParams(res, in_data);

});

pycaffe.js

const { spawn } = require('child_process');

var pycaffe = (function () {

var pycaffeInstance;

function create () {
var response;

console.log('Loading nets...');

const defaults = {
cwd: './nets',
env: process.env
};

var py = spawn('python', ['-i', 'deploy.py'], defaults);

py.stdout.on('data', function(data){
console.log(`stdout: ${data}`);
var fig = JSON.parse(data);

if(response !== undefined)
//send http response
response.send(fig)
//mutex.unlock()
});

function queryParams(res, data) {
//mutex.lock()
response = res;
py.stdin.write("query_params('"+data+"')\n");
}

return {
queryParams: queryParams
};
}

return {
getInstance: function() {
if(!pycaffeInstance) {
pycaffeInstance = create();
}
return pycaffeInstance;
}
};
})();

module.exports = pycaffe;

最佳答案

你不需要互斥量或信号量,因为在 Node 中你只有一个线程。如果有任何请求正在处理,您只需将请求存储在队列(可以是数组)中。当您通过 stdout 收到响应时,请检查队列是否包含另一个请求和进程。

你可以有一个基于 promise 的类似互斥锁的抽象。这是一个例子:

class Mutex {
constructor () {
this.queue = [];
this.locked = false;
}

lock () {
return new Promise((resolve, reject) => {
if (this.locked) {
this.queue.push([resolve, reject]);
} else {
this.locked = true;
resolve();
}
});
}

release () {
if (this.queue.length > 0) {
const [resolve, reject] = this.queue.shift();
resolve();
} else {
this.locked = false;
}
}
}

使用示例:

const mutex = new Mutex();

// using promise syntax
const handleRequest = () => {
mutex.lock().then(() => {
// do something here

mutex.release();
})
};

// using async syntax
const handleRequest = async () => {
await mutex.lock();

// do something here

mutex.release();
};

我用这段代码来测试:

const delay = ms => new Promise((resolve, reject) => setTimeout(resolve, ms));

let processNumber = 1;
const startProcess = async (mutex) => {
const thisProcessId = processNumber++;
console.log(new Date(), `started process ${thisProcessId}`);
await mutex.lock();
console.log(new Date(), `after lock ${thisProcessId}`);
await delay(3000);
mutex.release();
console.log(new Date(), `finished process ${thisProcessId}`);
};

(() => {
const mutex = new Mutex();
for (let i = 0; i < 5; i++) {
setTimeout(() => startProcess(mutex), Math.random() * 10000);
}
})();

... 得到了这个结果:

2018-02-01T19:02:36.418Z 'started process 1'
2018-02-01T19:02:36.421Z 'after lock 1'
2018-02-01T19:02:38.565Z 'started process 2'
2018-02-01T19:02:39.426Z 'finished process 1'
2018-02-01T19:02:39.426Z 'after lock 2'
2018-02-01T19:02:40.048Z 'started process 3'
2018-02-01T19:02:42.309Z 'started process 4'
2018-02-01T19:02:42.428Z 'finished process 2'
2018-02-01T19:02:42.428Z 'after lock 3'
2018-02-01T19:02:43.200Z 'started process 5'
2018-02-01T19:02:45.429Z 'finished process 3'
2018-02-01T19:02:45.429Z 'after lock 4'
2018-02-01T19:02:48.433Z 'finished process 4'
2018-02-01T19:02:48.433Z 'after lock 5'
2018-02-01T19:02:51.438Z 'finished process 5'

关于javascript - nodejs 中类似 c 的互斥量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48563969/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com