标签: blocking

使用select读取和写入相同的套接字(TCP)

我们正在写一个客户端和服务器(我认为是)非常简单的网络通信.多个客户端连接到服务器,然后服务器将数据发送回所有其他客户端.

服务器只是位于阻塞select循环中等待流量,当它到来时,将数据发送到其他客户端.这似乎工作得很好.

问题是客户.在阅读时,它有时会想要写一次.

但是,我发现如果我使用:

 rv = select(fdmax + 1, &master_list, NULL, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)

我的代码将阻塞,直到有新数据要读取.但有时(异步,来自另一个线程)我将在网络通信线程上写入新数据.所以,我希望我的select定期唤醒,让我检查是否有要写的数据,如:

if (select(....) != -1)
{
  if (FD_SET(sockfd, &master_list))
     // handle data or disconnect
  else
     // look for data to write and write() / send() those.
}
Run Code Online (Sandbox Code Playgroud)

我尝试将选择设置为轮询模式(或荒谬的短暂超时):

// master list contains the sockfd from the getaddrinfo/socket/connect seq
struct timeval t;
memset(&t, 0, sizeof t);
rv = select(fdmax + 1, &master_list, NULL, NULL, &t);
Run Code Online (Sandbox Code Playgroud)

但是发现那时客户端永远不会得到任何传入的数据.

我也尝试将socket fd设置为非阻塞,如:

fcntl(sockfd, F_SETFL, O_NONBLOCK);
Run Code Online (Sandbox Code Playgroud)

但这并没有解决问题:

  1. 如果我的客户端select()没有struct …

c sockets select read-write blocking

11
推荐指数
2
解决办法
2万
查看次数

调用者阻塞,直到getFoo()准备好了值?

我有一个Java Thread,它暴露了其他线程想要访问的属性:

class MyThread extends Thread {
   private Foo foo;
   ...
   Foo getFoo() {
     return foo;
   }
   ...
   public void run() { 
     ...
     foo = makeTheFoo();
     ...
   }
}
Run Code Online (Sandbox Code Playgroud)

问题是从运行到foo可用时需要很短的时间.呼叫者可以getFoo()在此之前致电并获得null.我宁愿他们只是阻塞,等待,并在初始化发生后获取值.(foo之后永远不会改变.)在它准备好之前它将是几毫秒,所以我对这种方法很满意.

现在,我可以通过这种方式实现这一目标,wait()并且notifyAll()有95%的可能性我会做得对.但我想知道你们都会怎么做; 有没有一个原始人java.util.concurrent会这样做,我错过了?

或者,你会如何构建它?是的,制造foo易变的.是的,在内部锁定上同步Object并将检查放入while循环中,直到它不是null.我错过了什么吗?

java multithreading synchronization properties blocking

11
推荐指数
1
解决办法
3480
查看次数

带有轮询的非阻塞套接字

几天前,我不得不调查我的应用程序在(显然)处于空闲状态时显示异常高CPU使用率的问题.我将问题跟踪到一个循环,这个循环意味着recvfrom在套接字被设置为O_NONBLOCK-ing 时阻塞一个调用,导致旋转锁定.有两种方法可以解决问题:使用poll或设置套接字阻塞或轮询套接字上的可用数据select.我选择前者因为它更简单.但我想知道为什么任何人会创建一个非阻塞套接字然后单独轮询它.阻塞套接字是否也这样做?使用非阻塞套接字和轮询组合的用例有哪些?在一般情况下它有什么优势吗?

c sockets posix blocking

11
推荐指数
2
解决办法
9715
查看次数

非阻塞套接字

在Java中实现非阻塞套接字的最佳方法是什么?

还是有这样的事情?我有一个通过套接字与服务器通信的程序,但是如果数据/连接出现问题,我不希望套接字调用阻塞/导致延迟.

java sockets network-programming nonblocking blocking

11
推荐指数
3
解决办法
2万
查看次数

什么时候应该抛出InterruptedException,我应该如何处理呢?(阻塞方法)

如果一种方法必须是阻止方法,我是否正确地认为如果我遗漏throws InterruptedException,我犯了一个错误?

简而言之:

  • 阻塞方法应该包括throws InterruptedException另外一种常规方法.
  • 阻塞方法可能会影响响应能力,因为很难预测它何时会完成,这就是它需要的原因throws InterruptedException.

那是对的吗?

java multithreading exception-handling blocking

11
推荐指数
3
解决办法
2万
查看次数

为什么新线程而不是未来{...}

此答案指示如何转换java.util.concurrent.Futurescala.concurrent.Future,同时管理阻塞将发生的位置:

import java.util.concurrent.{Future => JFuture}
import scala.concurrent.{Future => SFuture}

val jfuture: JFuture[T] = ???
val promise = Promise[T]()
new Thread(
  new Runnable {
    def run() { promise.complete(Try{ jfuture.get }) }
  }
).start
val future = promise.future
Run Code Online (Sandbox Code Playgroud)

我的问题与评论中提出的问题相同:

怎么了future { jfuture.get }?为什么你使用额外的线程与Promise结合?

答案如下:

它会在你的线程拉动中阻止线程.如果您为这样的期货配置了ExecutionContext,那很好,但是默认的ExecutionContext包含与处理器一样多的线程.

我不确定我理解这个解释.重申:

怎么了future { jfuture.get }?在手中创建一个新线程并在那里阻塞时,在未来内部是否阻塞?如果没有,它有什么不同?

java multithreading scala future blocking

11
推荐指数
2
解决办法
1131
查看次数

睡眠的行为和选择在去

我试图更多地了解在Go中各种阻塞/等待操作类型期间在表面下发生的事情.请看以下示例:

otherChan = make(chan int)
t = time.NewTicker(time.Second)
for {
    doThings()

    // OPTION A: Sleep
    time.Sleep(time.Second)

    // OPTION B: Blocking ticker
    <- t.C

    // OPTION C: Select multiple
    select {
        case <- otherChan:
        case <- t.C:
    }
}
Run Code Online (Sandbox Code Playgroud)

从低级别的视图(系统调用,cpu调度)这些等待时间有什么区别?

我的理解是time.Sleep让CPU自由执行其他任务,直到指定的时间结束.阻止股票代码是否<- t.C也这样做?处理器是否轮询通道或是否涉及中断?选择中有多个频道会改变什么吗?

换句话说,假设otherChan从未有任何东西投入其中,这三个选项是否会以相同的方式执行,还是会比其他选项的资源密集程度更低?

resources go blocking

11
推荐指数
1
解决办法
2037
查看次数

有没有办法让youtube的所有IP地址用Windows防火墙阻止它?

我想编写自己的抗干扰工具.我不能/不想使用主机或第三方应用程序.使用IPSEC或Windows防火墙时,它只接受IP地址.有

youtube.[264 TLD]
www.youtube.[264 TLD]
subdomains.youtube.[264 TLD]

显然,没有办法获得youtube子域的完整列表.

有人可以想办法以某种方式获取所有youtube ip地址并在ip级别阻止它们而不是使用暴力子域ping?

youtube ip firewall windows-firewall blocking

10
推荐指数
3
解决办法
15万
查看次数

为什么不调用`poll`在sysfs设备属性文件上正确阻塞?

我有一个简单的sysfs设备属性,显示在我的sysfs目录下,并在调用时read返回一个kernelspace变量的值.我想调用poll此属性以允许我的用户空间线程阻塞,直到属性显示的值发生更改.

我的问题是poll似乎没有阻止我的属性 - POLLPRI即使属性显示的值没有改变,它仍然会返回.实际上,我sysfs_notify在内核模块中根本没有调用,但用户空间调用poll仍然没有阻塞.

也许我应该检查比其他东西返回值POLLPRI-但根据文档的Linux内核,sysfs_poll应该返回POLLERR|POLLPRI:

/* ... When the content changes (assuming the
 * manager for the kobject supports notification), poll will
 * return POLLERR|POLLPRI ...
 */
Run Code Online (Sandbox Code Playgroud)

有什么我忘了做的事poll吗?


  1. device属性位于:/ sys/class/vilhelm/foo/blah.

  2. 我加载了一个名为foo的内核模块,它注册了一个设备,并创建了一个类和这个设备属性.

  3. 名为bar的用户空间应用程序生成一个调用poll设备属性的线程,检查POLLPRI.

    • 如果poll返回正数,POLLPRI则返回.
    • 使用fopenfscan从设备属性文件中读取值.
    • 如果值是 …

linux polling blocking linux-device-driver linux-kernel

10
推荐指数
1
解决办法
5545
查看次数

如何可靠地清理执行阻塞IO的Rust线程?

在Rust中生成阻塞IO的线程似乎是一个常见的习惯用法,因此您可以使用非阻塞通道:

use std::sync::mpsc::channel;
use std::thread;
use std::net::TcpListener;

fn main() {
    let (accept_tx, accept_rx) = channel();

    let listener_thread = thread::spawn(move || {
        let listener = TcpListener::bind(":::0").unwrap();
        for client in listener.incoming() {
            if let Err(_) = accept_tx.send(client.unwrap()) {
                break;
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

问题是,重新加入这样的线程取决于生成的线程"意识到"通道的接收端已经被丢弃(即,调用send(..)返回Err(_)):

drop(accept_rx);
listener_thread.join(); // blocks until listener thread reaches accept_tx.send(..)
Run Code Online (Sandbox Code Playgroud)

你可以为TcpListeners 创建虚拟连接,并TcpStream通过克隆关闭s,但这些似乎是清理这些线程的真正hacky方法,而且就目前而言,我甚至不知道在读取时触发线程阻塞的黑客攻击stdin加入.

我怎样才能清理这些线程,或者我的架构是错的?

multithreading channel blocking rust

10
推荐指数
1
解决办法
1171
查看次数