套接字和多线程

发布于 2024-08-30 02:34:53 字数 1580 浏览 5 评论 0原文

我有一个有趣的(对我来说)问题...有两个线程,一个用于从 std 输入捕获数据并通过套接字将其发送到服务器,另一个线程从阻塞套接字接收数据。那么,当服务器没有回复时,recv() 调用就会无限期地等待,对吧?但它不是仅阻塞其调用线程,而是阻塞整个进程!为什么会出现这种情况呢?

boost::mutex     nvtMutex;
boost::mutex    strMutex;
boost::mutex    quitMutex;
bool        quit = false;

void *processServerOutput(void *arg)
{
    NVT *nvt = (NVT*)arg;
    while(1)
    {
        // Lock the quitMutex before trying to access to quit variable
        quitMutex.lock();
        if(quit)
        {
            quitMutex.unlock();
            pthread_exit(NULL);
        }
        else
            quitMutex.unlock();

        // Receive output from server
        nvtMutex.lock();
        nvt->receive();
        cout << Util::Instance()->iconv("koi8-r", "utf-8", nvt->getOutBuffer());
        nvtMutex.unlock();

        // Delay
        sleep(1);
    }
}

void *processUserInput(void *arg)
{
    NVT *nvt = (NVT*)arg;

    while(1)
    {
        // Get user's input
        //cin.getline(str, 1023);

        sleep(3);
        strcpy(str, "hello");

        // If we type 'quit', exit from thread
        if(strcmp(str, "quit") == 0)
        {
            // Lock quit variable before trying to modify it
            quitMutex.lock();
            quit = true;
            quitMutex.unlock();

            // Exit from thread
            pthread_exit(NULL);
        }

        // Send the input to server
        nvtMutex.lock();
        nvt->writeUserCommand(Util::Instance()->iconv("utf-8", "koi8-r", str));
        nvt->send();
        nvtMutex.unlock();
    }
}

I have an interesting (to me) problem... There are two threads, one for capturing data from std input and sending it through socket to server, and another one which receives data from blocking socket. So, when there's no reply from server, recv() call waits indefenitely, right? But instead of blocking only its calling thread, it blocks the overall process! Why this thing occurs?

boost::mutex     nvtMutex;
boost::mutex    strMutex;
boost::mutex    quitMutex;
bool        quit = false;

void *processServerOutput(void *arg)
{
    NVT *nvt = (NVT*)arg;
    while(1)
    {
        // Lock the quitMutex before trying to access to quit variable
        quitMutex.lock();
        if(quit)
        {
            quitMutex.unlock();
            pthread_exit(NULL);
        }
        else
            quitMutex.unlock();

        // Receive output from server
        nvtMutex.lock();
        nvt->receive();
        cout << Util::Instance()->iconv("koi8-r", "utf-8", nvt->getOutBuffer());
        nvtMutex.unlock();

        // Delay
        sleep(1);
    }
}

void *processUserInput(void *arg)
{
    NVT *nvt = (NVT*)arg;

    while(1)
    {
        // Get user's input
        //cin.getline(str, 1023);

        sleep(3);
        strcpy(str, "hello");

        // If we type 'quit', exit from thread
        if(strcmp(str, "quit") == 0)
        {
            // Lock quit variable before trying to modify it
            quitMutex.lock();
            quit = true;
            quitMutex.unlock();

            // Exit from thread
            pthread_exit(NULL);
        }

        // Send the input to server
        nvtMutex.lock();
        nvt->writeUserCommand(Util::Instance()->iconv("utf-8", "koi8-r", str));
        nvt->send();
        nvtMutex.unlock();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

§对你不离不弃 2024-09-06 02:34:54

您将 nvtMutex 保存在对 NVT::recv 的调用中。由于两个线程都需要锁定互斥体才能完成迭代,因此在 NVT::recv 返回之前,另一个线程无法继续进行。

如果不知道此 NVT 类的详细信息,就不可能知道在调用 NVT::recv 之前是否可以安全地解锁互斥锁,或者该类是否未提供正确的线程您需要的安全。

You are holding the nvtMutex inside the call to NVT::recv. Since both threads need to lock the mutex to make it through an iteration, until NVT::recv returns the other thread can't progress.

Without knowing the details of this NVT class, it's impossible to know if you can safely unlock the mutex before calling NVT::recv or if this class does not provide the proper thread safety you need.

凉薄对峙 2024-09-06 02:34:54

如果您的代码实现正确,recv 只会阻塞调用它的线程。

如果您的情况并非如此,请显示演示该问题的最小代码示例。

If your code is implemented correctly, recv blocks only the thread that invokes it.

If this isn't the case for you, show the minimal code sample that demonstrates the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文