一个愚蠢的问题,但我真的无法让它工作:我在Swing应用程序中有一些长时间运行的过程可能需要几分钟.我希望在此过程正在进行时向用户显示进度对话框.我还想阻止用户执行进一步的操作,例如在进行过程中按下按钮.
如果我在EDT上执行此过程,这显然会阻止最终用户在进程中执行任何操作.但是因为EDT正在忙于处理,所以它永远无法渲染对话框的内容,因此我只是得到了对话框的轮廓.
但是如果我在工作线程中执行该过程,最终用户可以单击按钮并使EDT操纵工作者同时也在操作的状态,结果是坏事.如果我创建对话框模态,那不会发生,但Swing中的模态也意味着阻塞,所以在我调用的那一刻setVisible(true),线程永远阻塞.
所以我当前的"解决方案"是使用一个工作线程,然后产生一个单独的线程,其唯一目的是吸收阻塞性质setVisible.肯定有一个更好的解决方案!
那么我如何得到一个对话框,阻止用户与系统的其余部分(模态)交互,但不阻止导致它可见的线程?
正如标题所暗示的那样,我正在寻找一种比较和交换的实现,但是要比较大:
if(newValue > oldValue) {
oldValue = newValue;
}
Run Code Online (Sandbox Code Playgroud)
哪里oldValue是一些全局共享状态,并且newValue对每个线程都是私有的,而不执行以下操作:
synchronized(locker) {
if(newValue > oldValue) {
oldValue = newValue;
}
}
Run Code Online (Sandbox Code Playgroud)
因为我想要一个非阻塞的解决方案.通过研究其他非阻塞操作的源代码,我想出了这个(假设值是整数):
AtomicInteger oldValue; // shared global variable
...
public boolean GreaterThanCAS(int newValue) {
while(true) {
int local = oldValue;
if(local == oldValue) {
if(newValue > local) {
if(oldValue.compareAndSet(local, newValue) {
return true; // swap successful
} // else keep looping
} else {
return false; // swap failed
}
} // else keep looping
} …Run Code Online (Sandbox Code Playgroud) 在Java或C#或其他一些语言中,存在非阻塞IO设施,例如,用于套接字.
所以我可以将我的回调函数提供给非阻塞IO,一旦非阻塞IO收到任何东西,它就会调用我的回调函数.
我想知道它们是如何实施的.如果我在场景后面创建非阻塞IO,那么Java或C#是否只为它们创建了后台线程?或OS底层有本机支持吗?
我读了这篇文章如何真正地,真正地使用QThreads; 完整解释,它说而不是子类qthread,并重新实现run(),应该使用moveToThread使用moveToThread(QThread*)将QObject推送到QThread实例
这是c ++示例,但我不知道如何将其转换为python代码.
class Worker : public QObject
{
Q_OBJECT
QThread workerThread;
public slots:
void doWork(const QString ¶meter) {
// ...
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(this, SIGNAL(operate(QString)), worker, SLOT(doWork(QString)));
connect(worker, SIGNAL(resultReady(QString)), this, SLOT(handleResults(QString)));
workerThread.start();
}
~Controller() {
workerThread.quit();
workerThread.wait();
}
public slots:
void handleResults(const QString &);
signals:
void operate(const QString …Run Code Online (Sandbox Code Playgroud) 我只是通过示例PoC项目在简单的常见场景中测试一些阻塞/非阻塞解决方案.
我已经使用WebFlux测试了当前(阻塞)Spring启动客户端(tomcat),Spring Boot 2.0(netty) - WebClient,Ratpack和Lagom.在每种情况下,我都通过gatling测试简单场景(100-1000个用户/秒)强调了客户端应用程序.
我已经测试了ratpack和lagom作为参考非阻塞io服务器,以将结果与spring boot(阻塞和非阻塞)进行比较.
在所有情况下,我都有预期的结果,除了Spring boot 2.0测试.它仅适用于小负载水平,但即便如此,也具有高延迟.如果负载水平上升 - 所有请求都是时间.
WebClient用法:
@RestController
public class NonBlockingClientController {
private WebClient client = WebClient.create("http://localhost:9000");
@GetMapping("/client")
public Mono<String> getData() {
return client.get()
.uri("/routing")
.accept(TEXT_PLAIN)
.exchange()
.then(response -> response.bodyToMono(String.class));
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道出了什么问题或当前的快照版本只是工作.
所有来源均发布于https://github.com/rutkowskij/blocking-non-blocking-poc
我刚刚使用spring-boot-starter-webflux和版本2.0.0.BUILD-SNAPSHOT创建了一个简单的Spring Boot应用程序,它带来了spring-webflux版本5.0.0.BUILD-SNAPSHOT和Spring Core,Beans,Context等相同.
我想在Python中使用非阻塞方法写入文件.在一些谷歌上,我发现语言支持fcntl这样做,但实现相同的方法对我来说不是很清楚.
这是代码片段(我不知道我哪里出错了):
import os, fcntl
nf = fcntl.fcntl(0,fcntl.F_UNCLK)
fcntl.fcntl(0,fcntl.F_SETFL , nf | os.O_NONBLOCK )
nf = open ("test.txt", 'a')
nf.write ( " sample text \n")
Run Code Online (Sandbox Code Playgroud)
这是对文件执行非阻塞IO操作的正确方法吗?我对此表示怀疑.另外,你能否在Python中建议任何其他允许我这样做的模块?
众所周知,一些阻塞调用像read和write将返回-1,并设置errno到EINTR,我们需要处理这个问题.
我的问题是:这是否适用于非阻塞调用,例如,将套接字设置为O_NONBLOCK?
由于我读过的一些文章和消息来源称非阻塞调用不需要为此烦恼,但我没有找到关于它的权威参考.如果是这样,它是否适用于不同的实现?
非阻塞套接字的手册页中详细记录了两个案例:
没有记录的非阻塞套接字是:
是否可以安全地假设send()甚至会在一个字节的数据上返回EAGAIN/EWOULDBLOCK?或者,非阻塞程序是否应该再次发送()以获得结论性的EAGAIN/EWOULDBLOCK?我担心在插座上放一个EPOLLOUT观察器,如果它实际上没有处于"阻塞"状态以响应它的出现.
显然,后一种策略(再次尝试获得某种结论)具有明确定义的行为,但它更加冗长并且会对性能产生影响.
我正在学习Node.js,我已经读过Node.js是单线程和非阻塞的.
我有一个良好的JavaScript背景,我确实理解回调,但我真正不了解的是Node.js如何可以单线程并在后台运行代码.这不矛盾吗?
因为如果Node.js是单线程的,那么它仍然只能执行一个任务.因此,如果它在后台运行某些东西,它必须停止当前任务在后台处理某些东西,对吗?
这实际上是如何工作的?
关于将套接字设置为非阻塞模式,我已经读过这个.
http://www.gnu.org/software/libc/manual/html_mono/libc.html#File-Status-Flags
这是我做的:
static void setnonblocking(int sock)
{
int opts;
opts = fcntl(sock,F_GETFL);
if (opts < 0) {
perror("fcntl(F_GETFL)");
exit(EXIT_FAILURE);
}
opts = (opts | O_NONBLOCK);
if (fcntl(sock,F_SETFL,opts) < 0) {
perror("fcntl(F_SETFL)");
exit(EXIT_FAILURE);
}
return;
}
Run Code Online (Sandbox Code Playgroud)
如何将套接字设置回阻止模式?我没有看到O_BLOCK标志?
谢谢.
nonblocking ×10
java ×3
sockets ×3
c ×2
python ×2
blocking ×1
c# ×1
eintr ×1
file-io ×1
javascript ×1
linux ×1
modal-dialog ×1
networking ×1
node.js ×1
pyqt ×1
qthread ×1
spring ×1
spring-boot ×1
swing ×1