boost mutex

boost mutex

boost mutex

better use boost::shared_mutex!!
=> see boost::shared_mutex

essentials

  • mutable
  • scoped_lock

boost::mutex example

#include "boost/thread/mutex.hpp" /* mutex* */

class Some {
#define _DOBODIESLOCK() \
    boost::mutex::scoped_lock __lk(this->bodiesLock); \
    (void)(__lk)

    Foo getFoo(void) const
    {
        _DOBODIESLOCK();
        ...
        Foo ret = this->foo:
        ...
        return ret;
    }
    void setFoo(Foo const& foo)
    {
        _DOBODIESLOCK();
        ...
        this->foo = foo;
        ...
    }

    Foo foo;
    mutable boost::mutex bodiesLock;/* !! */
#  undef _DOBODIESLOCK
};

boost shared mutex

essentials

  • mutable
  • shared_lock for read
  • upgrade_lock and upgrade_to_unique_lock for write

example

#include "boost/thread/shared_mutex.hpp" /* shared_mutex */

class Some {
#define _DOSHAREDREAD() \
    boost::shared_lock<boost::shared_mutex> __rLock(this->rwlock); \
    (void)(__rLock)
#define _DOEXCLUSIVEWRITE() \
    boost::upgrade_lock<boost::shared_mutex> __uplock(this->rwlock); \
    boost::upgrade_to_unique_lock<boost::shared_mutex> __wLock(__uplock); \
    (void)(__wLock)

    Foo getFoo(void) const
    {
        _DOSHAREDREAD();
        ...
        Foo ret = this->foo:
        ...
        return ret;
    }
    void setFoo(Foo const& foo)
    {
        _DOEXCLUSIVEWRITE();
        ...
        this->foo = foo;
        ...
    }

    Foo foo;
    mutable boost::shared_mutex rwlock;
#  undef _DOSHAREDREAD
#  undef _DOEXCLUSIVEWRITE
}:

how to cpp (coding)

how to cpp (coding)

my cpp standard (style / specification / .. how to coding!)

#


list

simple thing should be simple

  • no redundant prefix, e.x. m / _ / i / ..
  • no redundant suffix, e.x. _ / ..
  • example not:
bool bShouldReboot;
int iNumber;
AAAA maaaa;
BBBB bbbb_;


/* then access example */
if (bShouldReboot) { /* where the bShouldReboot from */
}
bbbb_.foo(); /* where the bbbb_ from */

but should be:

bool shouldReboot;
int number;
AAAA aaaa;
BBBB bbbb;

/* then access example */
if (self.shouldReboot) { /* the shouldReboot is myself */
}

if (this->shouldReboot) {
}

this->bbbb.foo(); /* the bbbb from this object */

about ostream

  • better not use endl .. std::endl, but \n is ok !

indent

  • usually 1 is enough!!

example not

void somemaybeokfooMaybebadaaa(const AAAA& aaaa, const BBBB& bbbb,
                               const CCCC& cccc, const DDDD& dddd,
                               const EEEE& eeee);

but should be

void somemaybeokfooMaybebadaaa(
    const AAAA& aaaa,
    const BBBB& bbbb,
    const CCCC& cccc,
    const DDDD& dddd,
    const EEEE& eeee);

80

  • yes !! usually max width of each line is 80
  • 可以换行啊 !!!

no garbage

  • no garbage lines at middle of file
  • no garbage lines at end of file
  • no garbage space (space / table / ..) at end of line
  • no garbage space (space / table / ..) at begin of line(
    example, need 2 but 3 provided)

1 space

  • example not:
if(some){
}

sum=a+b;

but shoule be

if (some) {
}

sum = a + b;

block statement

  • always {}, even if 1 statement, example:
/* NOT */
some;
if (ok)
    fly();
else
    walk();
other;

/* BUT SHOULE BE: */
some;
if (ok) {
    fly();
} else {
    walk();
}
other;

/* and further more is good: */
some;
if (ok) {
    fly();
    saysomething();
} else {
    walk();
}
stopFirst();
other;

path

  • example for include: NOT ../../.hpp or ../.hpp
    or too/many/name/...hpp

but should be: some/…hpp and use -I...

lower and upper

  • type: Type
  • instance / member: instance / data / foo / staticFoo
  • generic function: Foo

prefix

  • better no! if could be simple !!
  • global: use k e.x. kGraphProcessor.
    (NOT use e.x. g)

plusplus

  • if not have to be some++(case for some++ when which can simplify 2 to 1)

SO USUALLY use ++some (not use some++ if not have to), because:
i see plus one, the result of the expression should be plused one !!
but this expression maybe little silly!

  • example, better:
for (size_t i = 0; i < sz; ++i) {
}

/* got whatsthis */
++whatsthis;/* should plus one or whatsthis += 1; */
someFoo(whatsthis);

when to declare

when to declare: when use, example

/* BAD: heyheyhey example */
Some heyheyhey;/* BAD */
doSome();
doOther();
thisFooNeedRefAndAlwaysSetIt(heyheyhey);

/* BAD: heyheyhey example 2 */
Some heyheyhey = 0;/* BAD */
...
thisFooNeedRefAndMaybeNotSetIt(heyheyhey);

/* BAD: heyheyhey example 3 */
Some heyheyhey;/* BAD */
heyheyhey = 0;/* BAD */
...
thisFooNeedRefAndMaybeNotSetIt(heyheyhey);

/* BAD: heyheyhey example 4 */
Some heyheyhey;/* BAD */
doSome();
...
heyheyhey = 0;/* BAD */
thisFooNeedRefAndMaybeNotSetIt(heyheyhey);

/* GOOD: heyheyhey example */
doSome();
doOther();
Some heyheyhey;/* GOOD ! */
thisFooNeedRefAndAlwaysSetIt(heyheyhey);

/* GOOD: heyheyhey example 2 */
doSome();
...
Some heyheyhey = 0;/* GOOD ! */
thisFooNeedRefAndMaybeNotSetIt(heyheyhey);

how to assign init

how to assign: do not assign repeatedly or maybe repeatedly, example

/* bad: */
size_t count = 10;
if (ok) {
    count  = 100;
}

/* good: */
size_t count;
if (ok) {
    count  = 100;
} else {
    count  = 10;
}

should dump when need

  • for data thread safe
  • for less call: if use not only once => dump it!, example
/*
 * consider now datas is latched .. here means
 * bad case:
 */
some();
for (size_t i = 0; i < datas.size(); ++i) {
    foo(datas[i]);
}
other();

/*
 * bad case 2:
 */
sayToSomebody(getNameById(1), "hi");
sayToSomebody(getNameById(1), "hey");

/*
 * consider now datas is latched .. here means
 * good case:
 */
some();
{
    const size_t sz = datas.size();/* dump the size */
    for (size_t i = 0; i < sz; ++i) {
        foo(datas[i]);
    }
}
other();

/*
 * good case 2:
 */
{
    const std::string who = getNameById(1);/* dump the name */
    sayToSomebody(who, "hi");
    sayToSomebody(who, "hey");
}

how to debug by output log

  • __FILE__
  • __LINE__
/* SO BAD example */
some();
std::cout << "aaaaa" << std::endl;
watch();
std::cout << "bbbbb222222!!!" << std::endl;/* what u b !! */

/* GOOD example */
some();
std::cout << "(" << __FILE__ << "+" << __LINE__ << ")" NAME " "
    << "before watch\n";/* good */
watch();
std::cout << "(" << __FILE__ << "+" << __LINE__ << ")" NAME " "
    << "after watch\n";/* good */

/* further more */
const int err = fly();
if (err) {
    std::cerr << "(" << __FILE__ << "+" << __LINE__ << ")" NAME " "
        << "ERROR: fly fail: " << err << "\n";/* so good */
    die();
}

no flag

  • just better NOT use the name flag, example:
/* bad case */
void setStartable(bool flag)
{
    this->startable = flag;
}

/* bad case 2 */
void setResult(bool flag)
{
    this->startable = flag;
}

/* good case: just to what it should be */
void setStartable(bool startable)
{
    this->startable = startable;
}

/* good case 2 */
void setResult(bool result)
{
    this->result = result;
}

further