简体   繁体   English

线程是否被ACE_SOCK_Stream的send()或recv()函数暂停?

[英]threads are halted by function send() or recv() of ACE_SOCK_Stream?

I am using pthread + ACE to write a fake client. 我正在使用pthread + ACE编写假客户端。

this client has 3 threads, and each thread could send and receive message endlessly by using ACE. 该客户端有3个线程,每个线程可以使用ACE无限地发送和接收消息。 however, these threads always be halted by the function send() or recv(). 但是,这些线程总是由send()或recv()函数暂停。 that is, the thread would exit if there is something wrong with sending or receiving, unfortunately, I don't know what is the error, and I could not catch it, too. 也就是说,如果发送或接收有问题,线程将退出,很遗憾,我不知道这是什么错误,我也无法捕获它。 the codes are: 这些代码是:

struct thread_data {
    int  thread_id;
    string ip;
    uint32_t port;
    uint32_t timeout;
};
std::vector<struct thread_data> m_thread;

void * test_fun1(void * threadid)
{
    struct thread_data * tmp_thread_data = (struct thread_data *)threadid;
    long tmp_threadid = (long)tmp_thread_data->thread_id;
    string tmp_ip = tmp_thread_data->ip;
    uint32_t tmp_port = tmp_thread_data->port;
    uint32_t tmp_timeout = tmp_thread_data->timeout;

    ACE_INET_Addr addr(tmp_port, tmp_ip.c_str());
    ACE_Time_Value timeout(0, tmp_timeout * 1000);
    ACE_SOCK_Connector connector;
    ACE_SOCK_Stream peer;

    // connect
    if(connector.connect(peer, addr, &timeout) != 0)
            pthread_exit((void *) threadid);

    // send msg
    while (1)
    {
            ssize_t tmp_ret1 = peer.send("hello world", 12);
            if (tmp_ret1 <= 0)
                    continue;

            char tmp_buf[1024] = '\0';
            ssize_t tmp_ret2 = peer.recv(tmp_buf, 1024, &timeout);
            if (tmp_ret2 <= 0)
                     continue;
            else
                     fprintf(stderr, "recv:%s\n", tmp_buf);
    }

    // close
    peer.close();
    pthread_exit((void *) threadid);
}

int main(int argc, char *argv[]) 
{
    std::vector<pthread_t> threads;
    pthread_attr_t attr;
    int rc;
    int i = 0;
    void * status;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    // thread create
    int tmp_num = 3;
    for(i = 0; i < tmp_num; i++)
    {
            pthread_t tmp_thread_handler;
            struct thread_data tmp_thread_info;
            tmp_thread_info.thread_id = i;
            tmp_thread_info.ip = "127.0.0.1";
            tmp_thread_info.port = 8001;
            tmp_thread_info.timeout = 100;
            rc = pthread_create(&tmp_thread_handler, NULL, test_fun1, (void *)&tmp_thread_info);
            if (rc != 0)
                    return -1;

            threads.push_back(tmp_thread_handler);
            m_thread.push_back(tmp_thread_info);
    }

    // thread start
    pthread_attr_destroy(&attr);
    for(i = 0; i < tmp_num; i++) 
    {

            rc = pthread_join(threads[i], &status);
            if (rc != 0) 
                    return -1;
    }

    pthread_exit(NULL);
    return 0; 
}

what should I do if I want to send and receive message endlessly? 如果我想不断发送和接收消息该怎么办? any help would be appreciated! 任何帮助,将不胜感激!

You have a significant scope-lifetime issue in this code. 在此代码中,您存在一个重大的范围生命周期问题。 You're sending a data block to your threads that is created/destroyed with each loop iteration. 您正在向线程发送一个数据块,该数据块是在每次循环迭代中创建/销毁的。 Leaving out the side-lines: 省略边线:

// thread create
int tmp_num = 3;
for(i = 0; i < tmp_num; i++)
{
    pthread_t tmp_thread_handler;
    struct thread_data tmp_thread_info;
    // --- snip ----
    rc = pthread_create(&tmp_thread_handler, NULL, test_fun1, (void *)&tmp_thread_info);
    // --- snip ----
}

Whether the resulting block is copied into the underlying info vectors or not is not relevant. 是否将生成的块复制到基础信息向量中无关紧要。 Once the loop slings around, the object is destroyed, and with it the std::string member variable ip . 循环结束后,对象将被销毁,并带有std::string成员变量ip It may reside in the same memory space (the struct), but the reallocation of the string almost certainly will not . 可以驻留在相同的内存空间(结构),但该字符串的再分配几乎肯定不会 In other words, you're invoking undefined behavior . 换句话说,您正在调用未定义的行为

A possible resolution to this is to use a smart pointer for the structure, passing its get() member to the thread, and pushing said-same smart pointer into your info vector ( retooled for smart pointers). 一种可能的解决方案是对结构使用智能指针,将其get()成员传递给线程,然后将相同的智能指针推入您的信息向量中(对智能指针进行重新设计)。 I personally prefer a simpler approach, namely allocating both vectors before the threads are kicked off, thereby fixing their "innards" for by-address usage. 我个人更喜欢一种更简单的方法,即启动线程之前分配两个向量,从而固定它们的“内部”以供按地址使用。 From there you can send the structure address since the vector holds it for you: 因为矢量为您保存了结构地址,所以您可以从那里发送结构地址:

// thread create
size_t tmp_num = 3;
m_thread.resize(tmp_num);
threads.resize(tmp_num);
for(size_t i = 0; i < tmp_num; i++)
{
    m_thread[i].thread_id = i;
    m_thread[i].ip = "127.0.0.1";
    m_thread[i].port = 8001;
    m_thread[i].timeout = 100;

    rc = pthread_create(&threads[i], NULL, test_fun1, &m_thread[i]);
    if (rc != 0)
        return -1;
}

Regarding other issues, in your thread proc this doesn't compile: 关于其他问题,在您的线程proc中无法编译:

char tmp_buf[1024] = '\0';

But that's pretty minor compared to the undefined behavior you're having. 但这与您未定义的行为相比是很小的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM