Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否可以在C、C+中使用类似Java的同步语句+;?_C++_C_Synchronization_Mutex_Synchronized - Fatal编程技术网

C++ 是否可以在C、C+中使用类似Java的同步语句+;?

C++ 是否可以在C、C+中使用类似Java的同步语句+;?,c++,c,synchronization,mutex,synchronized,C++,C,Synchronization,Mutex,Synchronized,我总是发现Java同步语句是一种干净的方式,可以实现互斥锁和解锁: public void addName(字符串名称){ 已同步(此){ lastName=名称; nameCount++; } 姓名列表。添加(姓名); } 尽管Java和pthread互斥体中使用的监视器的基本概念不同,但pthread互斥体最基本的用途通常是: void addName(char*name){ int status=-1; status=pthread\u mutex\u lock(此->锁); 如果(状态

我总是发现Java同步语句是一种干净的方式,可以实现互斥锁和解锁:

public void addName(字符串名称){
已同步(此){
lastName=名称;
nameCount++;
}
姓名列表。添加(姓名);
}
尽管Java和pthread互斥体中使用的监视器的基本概念不同,但pthread互斥体最基本的用途通常是:

void addName(char*name){
int status=-1;
status=pthread\u mutex\u lock(此->锁);
如果(状态==0){
此->lastName=名称;
此->名称计数++;
pthread_mutex_unlock(这个->锁);
}
名称列表->添加(名称);
}
我知道上面的代码并没有真正利用pthread互斥体的功能。它也不能处理所有的错误场景。然而,这可能是使用pthread互斥锁的最常见的方法。话虽如此,我认为对于这样的同步,有一个更简洁的习惯用法会更好:

public void addName(char*name){
已同步(此->锁定){
此->lastName=名称;
此->名称计数++;
}
姓名列表。添加(姓名);
}

< > >在C、C+++

> P>我们可以有如下类似的事情:

#定义同步锁定
#定义同步与锁定
#定义同步旋转_
#定义同步互斥_
#定义pthread\u rwlock\u wrunlock pthread\u rwlock\u unlock
#定义pthread\u rwlock\u rdunlock pthread\u rwlock\u unlock
#为(int_uuusync_status_uuu=!pthread_35;锁定类型(lockObj);u SYNC_status_uuu#锁定(lockObj);uuu SYNC_状态uuu;pthread_35;锁定类型#解锁(lockObj);uu SYNC_u状态u0)定义uuuu SYNC_j(lockObj,lockObj,lockType)
#为(int(同步)状态(锁定)=!pthread(互斥)锁(锁定);(同步)状态(锁定);pthread(互斥)解锁(锁定),(同步)状态(0)
#定义uuu SYNCALIAS_uuuu(_1,_2,NAME,…)名称
#定义uuu SYNC_uu(…)uuu SYNCALIAS_uuu(uu VA_ARGS_uuu,uuu SYNC_X_u,uu SYNC_M_u)(uu VA_ARGS_uu)
#定义同步(…)\uuuuuuuuuuuuuuuuuuuu同步(\uuuuu VA\u ARGS\uuuuuuuuuu)
这允许我们有两种风格的同步块-第一种仅用于互斥体:

已同步(此->锁定)
//==>\uuuu同步(此->锁定)
//==>\uuuu SYNCALIAS\uuuu(此->锁定,\uuuu SYNC\ux\uuuu,\uuuu SYNC\um\uu)(此->锁定)
//==>同步(此->锁定)
//==>for(int\uuuuu sync\u status\uuuuu=!pthread\u mutex\u lock(lockObj);\uuuuu sync\u status\uuuuuu;pthread\u mutex\u unlock(lockObj))
{
此->lastName=名称;
此->名称计数++;
}
或者,我们可以使用rwlocks、spinlocks甚至带有附加参数的互斥锁: -

问题是它不能干净地处理错误场景。所以也许有更好的方法。虽然这一个C和C++都可以工作,但是C++可能会有自己的解决方案。GCC扩展是我没有探索的另一条途径


在,.

中也做了一个参考实现,我发现
std::lock\u guard()
可以类似于Java的同步函数:

class MyType
{
    std::mutex mtx;

public:

    void synced_functionA()
    {
        std::lock_guard<std::mutex> lock(mtx);

        // synchronized code
    }

    void synced_functionB()
    {
        std::lock_guard<std::mutex> lock(mtx);

        // synchronized code
    }
};
类MyType
{
std::互斥mtx;
公众:
void synched_function()
{
标准:锁和防护锁(mtx);
//同步代码
}
void synched_functionB()
{
标准:锁和防护锁(mtx);
//同步代码
}
};

在C++中,RAII给出了几乎与“代码>同步的块”一样的整洁,并且因为C++ 11有一个标准的线程库,使用了:

{
    std::lock_guard<std::mutex> lock(mutex);
    lastName = name;
    nameCount++;
} // lock released here

nameList.add(name);
{
std::锁和保护锁(互斥锁);
lastName=名称;
nameCount++;
}//这里释放了锁
姓名列表。添加(姓名);

在C语言中,您必须按照描述手动获取并释放锁;它是一种更简单的语言,不支持自动资源管理。

经典方法是锁对象。一种小对象,其构造函数获取互斥体,其析构函数释放互斥体。在作用域内实例化lock对象与Java中的同步作用域具有相同的效果

C++11已经具备了实现这一点所需的一切,形式为
std::mutex
std::recursive\u mutex
std::unique\u lock

以下方法的结果与java中的同步方法几乎相同:

1) 声明一个
std::recursive_mutex
类成员

2) 获取方法中的互斥体

例如:

class whatever {

private:

    std::recursive_mutex s_mutex;

// ... The rest of the class definition.

public:

// ...
    void addName();

// ...
};

void whatever::addName()
{
    std::unique_lock<std::recursive_mutex> s_lock(s_mutex);

// ... the rest of the method
}
class无论什么{
私人:
std::递归_互斥体s_互斥体;
//…类定义的其余部分。
公众:
// ...
void addName();
// ...
};
void whatever::addName()
{
std::唯一_锁s_锁(s_互斥锁);
//…方法的其余部分
}
不必在整个方法范围内执行此操作:

void whatever::addName(char* name)
{
    {
        std::unique_lock<std::recursive_mutex> s_lock(s_mutex);

        this->lastName = name;
        this->nameCount++;
    }
    nameList.add(name);
}
void whatever::addName(char*name)
{
{
std::唯一_锁s_锁(s_互斥锁);
此->lastName=名称;
此->名称计数++;
}
姓名列表。添加(姓名);
}
总结如下:

< P> a)更新C++ 11,它提供POSIX互斥锁和锁的C++版本。
B) 如果无法更新到C++11,请编写自己的互斥和锁定方法。您希望避免执行显式的
pthread\u mutex\u lock
,每次都要自己解锁。很容易忘记在某个退出路径上显式解锁互斥锁,最终导致混乱。C++将为你做这件事,如果你把它们封装成类方法。

OWCH,这是一个简单的宏堆。你不应该使用。YEP,C++是RAII的,因此不需要宏。+ 1,我希望我能再次把它重新提出来,注意java <代码>同步< /COD>对象方法从同一线程中重新进入。标准的
std::mutex
将挂起来自同一线程的重入,而
std::recursive\u mutex
更符合Java同步的工作方式。(请参见关于重入的底部部分)。
void whatever::addName(char* name)
{
    {
        std::unique_lock<std::recursive_mutex> s_lock(s_mutex);

        this->lastName = name;
        this->nameCount++;
    }
    nameList.add(name);
}