Created
July 7, 2014 10:05
-
-
Save ochinchina/54f013aaff449cb6ecde to your computer and use it in GitHub Desktop.
implement barrier with the zookeeper C API, require C++11 compiler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CPP = g++ | |
INCS = -I$(ZK_DIR)/src/c/include -I$(ZK_DIR)/src/c/generated | |
LIBS = -L$(ZK_DIR)/src/c/.libs -lzookeeper_mt -lpthread | |
CXX_FLAGS = -std=c++11 | |
all: barrier | |
barrier: ZkBarrierTest.o | |
$(CPP) -o barrier ZkBarrierTest.o $(LIBS) | |
.cpp.o: | |
$(CPP) -c $(CXX_FLAGS) $(INCS) $< |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <zookeeper.h> | |
#include <iostream> | |
#include <string> | |
#include <unistd.h> | |
#include <mutex> | |
#include <condition_variable> | |
class ZkBarrier { | |
public: | |
ZkBarrier( const std::string& host, | |
const std::string& root, | |
const std::string& name, | |
int size ) | |
:host_( host ), | |
root_( root ), | |
name_( name ), | |
size_( size ), | |
connected_( false ) | |
{ | |
handle_ = zookeeper_init( host_.c_str(), watch, 5*1000, 0, this, 0 ); | |
{ | |
std::unique_lock<std::mutex> lock(mutex_); | |
while( !connected_) { | |
cond_.wait( lock ); | |
} | |
} | |
std::cout << "2, zookeeper connected" << std::endl; | |
Stat stat; | |
if( zoo_exists( handle_, root_.c_str(), false, &stat ) == ZOK ) { | |
std::cout << root_ << " already exists" << std::endl; | |
} else { | |
std::cout << root_ << " does not exist" << std::endl; | |
if( zoo_create( handle_, root_.c_str(), "simple test", 11, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0 ) == ZOK ) { | |
std::cout << "create " << root_ << " successfully" << std::endl; | |
} | |
} | |
} | |
~ZkBarrier() { | |
zookeeper_close( handle_ ); | |
} | |
void enter() { | |
std::string path = root_ + "/" + name_; | |
if( zoo_create( handle_, path.c_str(), "simple test", 11, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0 ) == ZOK ) { | |
std::cout << "create " << path << " successfully" << std::endl; | |
} | |
for( ; ; ) { | |
std::unique_lock<std::mutex> lock(mutex_); | |
String_vector children; | |
if( zoo_get_children( handle_, root_.c_str(), true, &children ) == ZOK ) { | |
if( children.count >= size_ ) { | |
deallocate_String_vector( &children ); | |
break; | |
} else { | |
deallocate_String_vector( &children ); | |
} | |
cond_.wait( lock ); | |
} | |
} | |
} | |
void leave() { | |
std::string path = root_ + "/" + name_; | |
if( zoo_delete( handle_, path.c_str(), -1 ) == ZOK ) { | |
std::cout << "delete " << path << " successfully" << std::endl; | |
} | |
} | |
private: | |
static void watch(zhandle_t *zh, int type, int state, const char *path,void *watcherCtx ) { | |
ZkBarrier* barrier = (ZkBarrier*)watcherCtx; | |
if( state == ZOO_CONNECTED_STATE || type == ZOO_CHILD_EVENT ) { | |
std::cout << "1, zookeeper connected" << std::endl; | |
{ | |
std::unique_lock<std::mutex> lock(barrier->mutex_); | |
barrier->connected_ = true; | |
} | |
barrier->cond_.notify_one(); | |
} | |
} | |
private: | |
std::string host_; | |
std::string root_; | |
std::string name_; | |
int size_; | |
zhandle_t* handle_; | |
bool connected_; | |
std::mutex mutex_; | |
std::condition_variable cond_; | |
}; | |
int main( int argc, char** argv ) { | |
ZkBarrier barrier("127.0.0.1:2181", "/root", argv[1], atoi( argv[2]) ); | |
barrier.enter(); | |
//TODO: do something you like | |
barrier.leave(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment