进程间对象传递

interprocess object passing

本文关键字:对象 进程      更新时间:2023-10-16

我需要有一个类,它有一个在自己的线程中每5秒执行一次的活动。它是一个web服务,因此需要指定一个端点。在对象运行时,主线程可以更改端点。这是我的课:

class Worker
{
    public:
    void setEndpoint(const std::string& endpoint); 
    private:
    void activity (void);
    mutex endpoint_mutex;
    volatile std::auto_ptr<std::string> newEndpoint;
    WebServiceClient client;
} 

newEndpoint对象是否需要声明为volatile?如果读取是在某个循环中,我当然会这样做(以使编译器不优化它),但在这里我不知道。

在每次运行中,activity()函数都会检查新的端点(如果有新的端点,则将其传递给客户端并执行一些重新连接步骤)并完成其工作。

void Worker::activity(void)
{
    endpoint_mutex.lock(); //don't consider exceptions
    std::auto_ptr<std::string>& ep = const_cast<std::auto_ptr<string> >(newEndpoint);
    if (NULL != ep.get())
    {
        client.setEndpoint(*ep);
        ep.reset(NULL);
        endpoint_mutex.unlock();
        client.doReconnectionStuff();
        client.doReconnectionStuff2();
    }
    else
    {
        endpoint_mutex.unlock();
    }
    client.doSomeStuff();
    client.doAnotherStuff();
    .....
}

我锁定了互斥锁,这意味着newEndpoint对象不能再更改,所以我删除了volatile类规范,以便能够调用const方法。

setEndpoint方法(从其他线程调用):

void Worker::setEndpoint(const std::string& endpoint)
{
    endpoint_mutex.lock(); //again - don't consider exceptions
    std::auto_ptr<std::string>& ep = const_cast<std::auto_ptr<string> >(newEndpoint);
    ep.reset(new std::string(endpoint);
    endpoint_mutex.unlock();
}

这东西线程安全吗?如果没有,问题出在哪里?我需要newEndpoint对象是易失性的吗?

volatile用于每个MSDN的以下情况:

volatile关键字是一个类型限定符,用于声明对象可以在程序中通过诸如操作系统、硬件或同时执行的线程。

声明为volatile的对象不用于某些优化因为它们的值可以随时更改。系统总是读取易失性对象在被请求时的当前值,即使先前的指令要求来自同一对象的值。此外,对象的值会在赋值时立即写入。

您的问题是,您的NewEndPoint实际更改的频率是多少?在线程a中创建一个连接,然后进行一些工作。在这种情况下,没有任何其他东西可以干扰您的端点,因为它被互斥锁锁住了。因此,根据我的分析,从我在代码中看到的情况来看,这个变量的变化并不一定足够。

我看不到你的类的调用站点,所以我不知道你是在使用同一个类实例100次还是更多次,或者你是在创建新对象。

这是在询问某个东西是否应该是volatile时需要进行的分析。

此外,关于线程安全,这些函数中会发生什么:

 client.doReconnectionStuff();
 client.doReconnectionStuff2();

他们是否使用了Worker类中的任何共享状态?它们是否共享和修改其他线程使用的任何其他状态?如果是,则需要进行适当的同步。

如果没有,那么你没事。

线程需要一些思考,你需要问自己这些问题。你需要看看所有的州,想知道你是否在分享。如果你在处理指针,那么你需要知道谁拥有这个指针,以及你是否在线程之间共享过它,无论是否意外,并采取相应的行动。如果您将指针传递给在另一个线程中运行的函数,则表示您正在共享指针所指向的对象。如果您在这个新线程中更改指针所指向,则表示正在共享并需要同步。