8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

在同一个套接字上并行调用 send/recv 是否有效?

Mikey 2月前

138 0

我们可以在同一个套接字上从一个线程调用发送并从另一个线程调用接收吗?我们可以在同一个套接字上从不同的线程并行调用多个发送吗?我知道一个好的设计应该避免这种情况......

  1. 我们可以在同一套接字上从一个线程调用 send 并从另一个线程调用 recv 吗?
  2. 我们可以从同一个套接字上的不同线程并行调用多个发送吗?

我知道一个好的设计应该避免这种情况,但我不清楚这些系统 API 将如何表现。我找不到关于此问题的良好文档。

任何方向的指示都会有帮助。

帖子版权声明 1、本帖标题:在同一个套接字上并行调用 send/recv 是否有效?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Mikey在本站《sockets》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 为什么你声称这样做是不好的做法?在我看来这很好,因为你在不同的线程中收听和接收消息。

  • POSIX 将 send/recv 定义为原子操作,因此假设您正在谈论 POSIX send/recv,那么是的,您可以从多个线程同时调用它们,并且一切正常。

    这并不一定意味着它们将并行执行——在多次发送的情况下,第二个可能会阻塞,直到第一个完成。您可能不会注意到这一点,因为一旦将数据放入套接字缓冲区,发送就会完成。

    如果您使用 SOCK_STREAM 套接字,尝试并行执行操作不太可能有用,因为 send/recv 可能只发送或接收消息的一部分,这意味着事情可能会被分裂。

    SOCK_STREAM 套接字上的阻塞发送/接收只会阻塞到它们发送或接收至少 1 个字节,因此阻塞和非阻塞之间的差异没有用。

  • @Joao:SOCK_DGRAM 套接字被记录为“保留消息边界”,但这并不十分清楚。通过查看 Linux 内核源代码,您至少可以看到每个发送和接收都以原子方式处理单个数据包(至少对于 udp 而言)。

  • @Kedar:不确定你的意思。一旦数据被放入发送缓冲区,发送就会返回,并且数据会通过网络堆栈异步发送到网络上。因此,如果你有一个发送线程和一个接收线程,那么在接收线程收到第一个数据包之前,发送线程完全有可能(甚至很可能)发送许多数据包。它完全是异步的,而不是同时的。

  • @ChrisDodd,您能给出“POSIX 将 send/recv 定义为原子操作”的链接吗?

  • @suitianshi:POSIX 1003.1c 标准文档列出了 1003.1 中所有可重入(可安全地从线程调用)和不可重入的函数。遗憾的是,我不知道有任何地方有可用的免费在线副本。

  • @ChrisDodd 我在 unix-systems.org/version4 上找到了副本,我可以看到第 7.1 章中的系统接口表列表,但没有看到其中将函数列为原子操作。不是怀疑你,但你能分享/编辑你的答案来证明你在文档中的观点吗?

  • 套接字描述符属于进程,而不是特定线程。因此,可以在不同线程中向同一套接字发送/接收数据,操作系统将处理同步。

    但是,如果发送/接收的顺序在语义上很重要,您自己(分别是您的代码)必须确保不同线程中的操作之间的正确排序 - 线程总是如此。

  • 我看不出并行接收如何能完成任何事情。如果您有一条 3 字节的消息,那么 1 个线程可以获取前 2 个字节,另一个线程可以获取最后一个字节,但您无法分辨哪个是哪个。除非您的消息只有一个字节长,否则您无法通过多个线程接收来可靠地完成任何事情。

    则多次发送 可能会 有效,但我不确定。有可能一个消息会覆盖另一个消息。这样做肯定不会带来任何性能上的好处。

    如果需要多个线程发送,则应实现同步消息队列。让一个线程执行实际发送操作,从队列中读取消息,让其他线程将整个消息入队。接收操作也同样有效,但接收线程必须知道消息的格式,以便能够正确地反序列化它们。

  • 如果你使用 SOCK_DGRAM 套接字,每个 recv 都会得到一个数据报;它将永远不会在 recv 之间分割

  • @noah,我同意并行接收无法完成任何事情。这就是我没有问这个问题的原因。我的问题是并行发送/接收,然后并行发送多个。您的回答确实深入了解了并行发送。同样感谢您的回答。

  • @Chris 说得好。我假设是 TCP。@Jay 你可能会澄清这个问题“我们可以并行调用发送/接收吗”,听起来你想并行接收。

  • @noah 如果我理解正确的话,您说的是一个线程用于发送消息,而另一个线程用于接收消息。我说得对吗?使用同一个线程读取和发送消息怎么样?

  • 我有一个文本动画,我希望原始文本向上移动并在鼠标悬停时显示新文本。但是,次要文本 (nav-hidden-text) 的顺序动画不起作用

    我有一个文本动画,我希望原始文本向上移动并在悬停时显示新文本。但是,次要文本 (nav-hidden-text) 的顺序动画在第一次悬停时无法正常工作。它在后续悬停和离开时工作正常,但初始悬停不会按预期触发序列。

    document.querySelectorAll('.nav-container').forEach(container => {
        let isHovering = false;
        let timeoutId = null;
    
        function updateTransitionDelays() {
            container.querySelectorAll('.nav-text .letter').forEach((letter, index) => {
                letter.style.transitionDelay = `${index * 0.05}s`;
            });
            container.querySelectorAll('.nav-hidden-text .letter').forEach((letter, index) => {
                letter.style.transitionDelay = `${(index * 0.05) + 0.2}s`;
            });
        }
    
        function forceReflow() {
            container.offsetHeight; // Forces a reflow to ensure animation starts
        }
    
        container.addEventListener('mouseenter', () => {
            isHovering = true;
            clearTimeout(timeoutId);
    
            // Force reflow
            requestAnimationFrame(() => {
                container.classList.add('hover');
                container.classList.remove('leave');
                updateTransitionDelays();
                forceReflow(); // Forces reflow to update styles
            });
        });
    
        container.addEventListener('mouseleave', () => {
            isHovering = false;
    
            // Force reflow
            requestAnimationFrame(() => {
                updateTransitionDelays();
                timeoutId = setTimeout(() => {
                    if (!isHovering) {
                        container.classList.add('leave');
                        container.classList.remove('hover');
                    }
                }, 50); // Adjust time as needed
            });
        });
    });
    .nav-container {
        display: inline-block;
        width: 200px;
        height: 35px;
        position: relative;
        overflow: hidden;
        font-size: 24px;
        text-align: center;
        color: #333;
        font-family: Arial, sans-serif;
    }
    
    .nav-link {
        display: block;
        position: relative;
        text-decoration: none;
        color: inherit;
        height: 100%;
    }
    
    .nav-text, .nav-hidden-text {
        position: absolute;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
        white-space: nowrap;
        top: 0;
        transition: top 0.4s ease;
    }
    
    .nav-text {
        z-index: 1;
    }
    
    .nav-hidden-text {
        top: 100%;
        z-index: 0;
        transition: top 0.4s ease; /* Ensure this is set */
    }
    
    .letter {
        display: inline-block;
        transition: transform 0.4s ease, opacity 0.4s ease;
    }
    
    .nav-container.hover .nav-text .letter {
        transform: translateY(-100%);
        opacity: 0;
    }
    
    .nav-container.hover .nav-hidden-text {
        top: 0;
        z-index: 1;
    }
    
    .nav-container.hover .nav-hidden-text .letter {
        transform: translateY(0);
        opacity: 1;
    }
    
    .nav-container.leave .nav-text .letter {
        transform: translateY(0);
        opacity: 1;
    }
    
    .nav-container.leave .nav-hidden-text {
        top: 100%;
        z-index: 0;
    }
    
    .nav-container.leave .nav-hidden-text .letter {
        transform: translateY(100%);
        opacity: 0;
    }
    <div class="nav-container">
        <a href="#" class="nav-link">
            <div class="nav-text">
                <span class="letter">O</span>
                <span class="letter">r</span>
                <span class="letter">i</span>
                <span class="letter">g</span>
                <span class="letter">i</span>
                <span class="letter">n</span>
                <span class="letter">a</span>
                <span class="letter">l</span>
                <span class="letter"> </span>
                <span class="letter">T</span>
                <span class="letter">e</span>
                <span class="letter">k</span>
                <span class="letter">s</span>
                <span class="letter">t</span>
            </div>
            <div class="nav-hidden-text">
                <span class="letter">N</span>
                <span class="letter">y</span>
                <span class="letter"> </span>
                <span class="letter">T</span>
                <span class="letter">e</span>
                <span class="letter">k</span>
                <span class="letter">s</span>
                <span class="letter">t</span>
            </div>
        </a>
    </div>

    nav-hidden-text 的顺序动画在第一次悬停时无法正常工作。在后续悬停和离开时,动画表现正常。nav-text 向上移动,nav-hidden-text 取代其位置。当鼠标未悬停时,nav-hidden-text 向下移动,nav-text 返回其原始位置。

    我尝试过的:确保正确应用过渡和动画属性。使用 JavaScript 强制重排并更新过渡延迟。验证 CSS 中的过渡和动画是否正确设置。

  • 我有一个 id = \'myIframe\' 的 iframe,这里是我的加载其内容的代码:$('#myIframe').attr(\'src\', \'my_url\'); 问题是有时加载时间太长,有时加载...

    我有一个 id = \'myIframe\' 的 iframe,这里是我的代码来加载它的内容:

    $('#myIframe').attr("src", "my_url");
    

    问题是,有时加载时间太长,有时加载速度很快。所以我必须使用 \'setTimeout\' 函数:

    setTimeout(function(){
       if (//something shows iframe is loaded or has content)
       {
           //my code
       }
       else
       {
           $('#myIframe').attr("src",""); //stop loading content
       }
    },5000);
    

    我只想知道如何确定 iFrame 是否已加载或是否有内容。使用 iframe.contents().find() 不起作用。我不能使用 iframe.load(function(){}) .

  • mgns 2月前 0 只看Ta
    引用 17

    谢谢你的帮助 :)。是的,如果加载时间超过 5 秒,我不希望 iframe 加载任何内容。使用 \'.ready()\' 不起作用,正如你下面显示的。

  • 尝试这个。

    <script>
    function checkIframeLoaded() {
        // Get a handle to the iframe element
        var iframe = document.getElementById('i_frame');
        var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
    
        // Check if loading is complete
        if (  iframeDoc.readyState  == 'complete' ) {
            //iframe.contentWindow.alert("Hello");
            iframe.contentWindow.onload = function(){
                alert("I am loaded");
            };
            // The loading is complete, call the function we want executed once the iframe is loaded
            afterLoading();
            return;
        } 
    
        // If we are here, it is not loaded. Set things up so we check   the status again in 100 milliseconds
        window.setTimeout(checkIframeLoaded, 100);
    }
    
    function afterLoading(){
        alert("I am here");
    }
    </script>
    
    <body onload="checkIframeLoaded();"> 
    
  • 传递字符串给 setTimeout() 有缺点。传递函数引用更简洁:setTimeout(checkIframeLoaded, 100);

  • ViSa 2月前 0 只看Ta
    引用 20

    这导致 \'不安全的 JavaScript 尝试从具有 url2 的框架访问具有 URL url1 的框架域、协议和端口必须匹配。\'

返回
作者最近主题: