同样的程序,在centos和ubuntu上都没有问题,在solaris上问题却多多,据说是solaris管理更加严格。

zookeeper_init方法,在传入一个错误的host也能初始化出一个非空的handle,只能通过state去判断是否连接上。

另外,在centos上使用zookeeper_mt才能连上zk,而在solaris上却不行。

分析src/c中的两个工具cli_st和cli_mt,发现cli_mt连不上,而cli_st可以连接。于是兴冲冲的将编译选项的库改为了-lzookeeper_st,结果返回的handle非空,高兴坏了,以为成功了,结果呢~,状态显示为连接失败:error code 999,这就是还没有连接上的表现。

于是开始分析为什么cli_st工具可以连接上,代码/src/cli.c文件中没有什么特殊的,那就应该是编译选项的问题了:

gcc -DHAVE_CONFIG_H -I.  -I./include -I./tests -I./generated -D_POSIX_PTHREAD_SEMANTICS  -Wall -Werror  -g -O0 -D_GNU_SOURCE -MT cli.o -MD -MP -MF .deps/cli.Tpo -c -o cli.o `test -f 'src/cli.c' || echo './'`src/cli.c
mv -f .deps/cli.Tpo .deps/cli.Po
/bin/sh ./libtool --tag=CC --mode=link gcc -Wall -Werror -g -O0 -D_GNU_SOURCE -o cli_st cli.o libzookeeper_st.la
libtool: link: gcc -Wall -Werror -g -O0 -D_GNU_SOURCE -o cli_st cli.o ./.libs/libzookeeper_st.a -lnsl -lsocket -lm

首先要弄懂libzookeeper_mt.so 和 libzookeeper_st.so有啥区别:

zookeeper的C客户端分为mt库和st库(多线程和单线程),一般操作都是以多线程库为主。

先记录到这里,稍后给结果。

问题原因:

关于C开发,zookeeper提供了两个库:zookeeper_st(单线程库)与zookeeper_mt(多线程库)。zookeeper_st放弃了事件循环,可在事件驱动的应用程序中使用。而zookeeper_mt更加易用,与Java API类似,创建一个网络IO线程和一个事件分发线程,用来维护连接和执行回调。

在具体使用上,zookeeper_st仅提供了异步API与回调,用以集成至应用程序的事件循环。它只是为了支持pthread库不可用或不稳定的平台而存在,例如FreeBSD 4.x。除此以外的其他情况,应使用提供同步与异步两种API的zookeeper_mt。

采用zookeeper_mt库的zookeeper客户端使用了3个线程:
线程1是业务逻辑层,负责与用户直接交互,主要是zookeeper库提供的API
线程2是网络IO层,负责与zookeeper服务端的网络通信,包括发送业务逻辑层的API调用生成的请求数据、服务端的响应数据、服务端的watch事件数据
线程3是事件处理层,负责执行watch回调

问题是在要将程序改为事件驱动非常麻烦,API也需要由同步改为异步,工作量相当大,接下来我们需要看看为什么在solaris上不能用多线程

最终解决方法:

最终使用gdb调试c目录下的cli_mt工具,找到connect出错的地方,在zookeeper.c 1612行,socket连接connect时出错。这里只打印出了错误编号errno,但是编号值为0,应该不对。可能这个编号不是线程安全的,可能是被别的线程改了值。

因此添加了perror来打印具体的错误:Operation now in progress

搜索了下该错误,说是套接字阻塞,把fcntl(x,x, O_NONBLOCK)放在connect之后 居然就没有这个错误了,于是也试试,竟然就解决了。 

详解:引用自http://www.bkjia.com/article/29653.html

zookeeper 的多线程和单线程库使用对比

我们都知道zookeeper提供了两个库,zookeeper_st和 zookeeper_mt。

前者是单线程库,仅仅提供了异步API和集成在应用程序实现循环中的回调函数,这个库是为了支持pthread库不支持或者不稳定的系统而存在的。使用过程中要自己通过zoo_interest和zoo_process实现事件处理及通知机制。

其他情况下应该使用后者多线程库。因为它同时支持同步和异步API。使用起来也方便很多,可以看我的例子。

The package includes two shared libraries: zookeeper_st and zookeeper_mt. The former only provides the asynchronous APIs and callbacks for integrating into the application's event loop. The only reason this library exists is to support the platforms were a pthread library is not available or is unstable (i.e. FreeBSD 4.x). In all other cases, application developers should link with zookeeper_mt, as it includes support for both Sync and Async API.

OK,talk is cheap。

单线程库使用示例:

在zookeeper上先创建/xyz才能执行成功,因为st库仅支持异步,而异步create没有时序保证。 该程序可以监控/xyz节点及子节点的变化。

#include
#include 
#include string.h>
#include 
#include 
#include 
#define TRUE 1static const char* state2String(int state)
{
if (state == 0)return "CLOSED_STATE";
if (state == ZOO_CONNECTING_STATE)return "CONNECTING_STATE";
if (state == ZOO_ASSOCIATING_STATE)return "ASSOCIATING_STATE";
if (state == ZOO_CONNECTED_STATE)return "CONNECTED_STATE";
if (state == ZOO_EXPIRED_SESSION_STATE)return "EXPIRED_SESSION_STATE";
if (state == ZOO_AUTH_FAILED_STATE)return "AUTH_FAILED_STATE";
return "INVALID_STATE"; }
static const char* type2String(int state)
{if (state == ZOO_CREATED_EVENT)return "CREATED_EVENT";
if (state == ZOO_DELETED_EVENT)return "DELETED_EVENT";
if (state == ZOO_CHANGED_EVENT)return "CHANGED_EVENT";
if (state == ZOO_CHILD_EVENT)return "CHILD_EVENT";
if (state == ZOO_SESSION_EVENT)return "SESSION_EVENT";
if (state == ZOO_NOTWATCHING_EVENT)return "NOTWATCHING_EVENT";return "UNKNOWN_EVENT_TYPE";
}
void zktest_dump_stat(const struct Stat *stat) 
{char tctimes[40];char tmtimes[40];
    time_t tctime;
    time_t tmtime;if (!stat) 
    {
        fprintf(stderr,"null\n");
        return;
    }
    tctime = stat->ctime/1000;
    tmtime = stat->mtime/1000;     ctime_r(&tmtime, tmtimes);
    ctime_r(&tctime, tctimes);     fprintf(stderr, "\tctime = %s\tczxid=%llx\n""\tmtime=%s\tmzxid=%llx\n""\tversion=%x\taversion=%x\n""\tephemeralOwner = %llx\n",
            tctimes, stat->czxid,
            tmtimes, stat->mzxid,
            (unsigned int)stat->version, (unsigned int)stat->aversion,
            stat->ephemeralOwner);
}
void zktest_data_completion(int rc, const char *value, int value_len, const struct Stat *stat, const void *data)
 {
    fprintf(stderr, "in data completion [%s]: rc = %d\n", value, rc);
    zktest_dump_stat(stat);
}
/*process a list of string and stat*/void zktest_strings_stat_completion(int rc, const struct String_vector *strings, const struct Stat *stat, const void *data)
 {int i=0;
    fprintf(stderr, "in strings state completion [%s]: rc = %d, string count %d\n", (char *)data, rc, strings ->count);for (i=0; icount; i++) {
        printf("%d: %s\n", i, strings->data[i]);
    }
deallocate_String_vector(strings);
    zktest_dump_stat(stat);
}void zktest_string_completion(int rc, const char *name, const void *data)
 {
    fprintf(stderr, "in string completion [%s]: rc = %d\n", (char*)(data==0?"null":data), rc);
    if (!rc)
     {
        fprintf(stderr, "\tname = %s\n", name);
    }
}void zktest_stat_completion(int rc, const struct Stat *stat, const void *data)
 {if (rc == ZNONODE)
    {
        printf("node not exists\n");
    }
    fprintf(stderr, "in state completion rc = %d data=%s stat:\n", rc, (char *)data);
    zktest_dump_stat(stat); }void zktest_void_completion(int rc, const void *data) {
    fprintf(stderr, "in void completion [%s]: rc = %d\n", (char*)(data==0?"null":data), rc);
}void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx) {
    printf("Something happened.\n");
    printf("type: %s\n", type2String(type));
    printf("state: %s\n", state2String(state));
    printf("path: %s\n", path);
    printf("watcherCtx: %s\n", (char *)watcherCtx);int ret;const clientid_t *zk_clientid;if (path == NULL || strlen(path) == 0)
    {
        path="/xyz";
    }if (type == ZOO_SESSION_EVENT)  {if (state == ZOO_EXPIRED_SESSION_STATE) {
            printf("[%s %d]zookeeper session expired\n", __FUNCTION__, __LINE__);
        } else if (state == ZOO_CONNECTED_STATE) {
            zk_clientid = zoo_client_id(zh);
            printf("[%s %d] connected to zookeeper server with clientid=%lu\n", __FUNCTION__, __LINE__, zk_clientid ->client_id);if ((ret=zoo_aexists(zh, path, TRUE, zktest_stat_completion, path)) != ZOK)
            {
                printf("[%s %d] zoo_aexists judge error, msg = %s\n", __FUNCTION__, __LINE__, zerror(ret));             }if ((ret = zoo_aget(zh, (char *)path, TRUE, zktest_data_completion, "get param")) !=ZOK)
            {
                printf("[%s %d] fail to get znode %s, err=%d, msg= %s\n", __FUNCTION__, __LINE__, path, ret, zerror(ret));
            }if ((ret = zoo_aget_children2(zh, path, TRUE, zktest_strings_stat_completion, "get children param")) !=ZOK)
            {
                printf("[%s %d] fail to get znode %s, err=%d, msg= %s\n", __FUNCTION__, __LINE__, path, ret, zerror(ret));
            }
        }
    } else if (type == ZOO_CREATED_EVENT) {
        printf("create a child node\n");if ((ret = zoo_aget_children2(zh, path, TRUE, zktest_strings_stat_completion, "get children param")) !=ZOK) {
            printf("[%s %d] fail to get znode %s, err=%d, msg= %s\n", __FUNCTION__, __LINE__, path, ret, zerror(ret));
        }if ((ret = zoo_aget(zh, path, TRUE, zktest_data_completion, "get param")) !=ZOK) {
            printf("[%s %d] fail to get znode %s, err=%d, msg= %s\n", __FUNCTION__, __LINE__, path, ret, zerror(ret));
        }     } else if (type == ZOO_DELETED_EVENT) {
        printf("path %s deleted\n", path);if ((ret = zoo_aget(zh, path, TRUE, zktest_data_completion, "get param")) !=ZOK) {
            printf("[%s %d] fail to get znode %s, err=%d, msg= %s\n", __FUNCTION__, __LINE__, path, ret, zerror(ret));
        }
    } else if (type == ZOO_CHANGED_EVENT) {
        printf("path %s changed\n", path);if ((ret = zoo_aget_children2(zh, path, TRUE, zktest_strings_stat_completion, "get children param")) !=ZOK) {
            printf("[%s %d] fail to get znode %s, err=%d, msg= %s\n", __FUNCTION__, __LINE__, path, ret, zerror(ret));
        }if ((ret = zoo_aget(zh, path, TRUE, zktest_data_completion, "get param")) !=ZOK) {
            printf("[%s %d] fail to get znode %s, err=%d, msg= %s\n", __FUNCTION__, __LINE__, path, ret, zerror(ret));
        }     } else if (type == ZOO_CHILD_EVENT) {
        printf("path %s child event\n");if ((ret = zoo_aget(zh, path, TRUE, zktest_data_completion, "get param")) !=ZOK) {
            printf("[%s %d] fail to get znode %s, err=%d, msg= %s\n", __FUNCTION__, __LINE__, path, ret, zerror(ret));
        }if ((ret = zoo_aget_children2(zh, path, TRUE, zktest_strings_stat_completion, "get children param")) !=ZOK) {
            printf("[%s %d] fail to get znode %s, err=%d, msg= %s\n", __FUNCTION__, __LINE__, path, ret, zerror(ret));
        }
    }else if (type == ZOO_NOTWATCHING_EVENT){
    }else {
        printf("unkown zoo event type\n");
    } }int main(int argc, const char *argv[])
{static const char* host = "localhost:2181";int timeout = 30000;
    zhandle_t* zkhandle;
    zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
    zoo_deterministic_conn_order(1);
    zkhandle = zookeeper_init(host, zktest_watcher_g, 30000, 0, "hello world", 0);if (zkhandle == NULL) {
        fprintf(stderr, "Error when connecting to zookeeper servers...\n");
        exit(EXIT_FAILURE);
    }/* Wait for asynchronous zookeeper call done.*/int fd, interest, events;int rc;
    fd_set rfds, wfds, efds;
    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    FD_ZERO(&efds);while(1){struct timeval tv;
        zookeeper_interest(zkhandle, &fd, &interest, &tv);if (fd != -1) {if(interest&ZOOKEEPER_READ)
            {
                FD_SET(fd, &rfds);
            } else {
                FD_CLR(fd, &rfds);
            }if(interest&ZOOKEEPER_WRITE)
            {
                FD_SET(fd, &wfds);
            } else{
                FD_CLR(fd, &wfds);
            }
        } else{
            fd = 0;
        }if (select(fd+1, &rfds, &wfds, &efds, &tv) < 0)
        {
            printf("[%s %d]select failed, err=%d, msg=%s\n", __FUNCTION__, __LINE__, errno, strerror(errno));
        }
        events = 0;if (FD_ISSET(fd, &rfds))
        {
         events |= ZOOKEEPER_READ;
        }if (FD_ISSET(fd, &wfds))
        {
            events |= ZOOKEEPER_WRITE;
        }
        zookeeper_process(zkhandle, events);
    }
    zookeeper_close(zkhandle);
}

gcc -o zookeeper_s_test zookeeper_s_test.c -lzookeeper_st -I /usr/local/include/zookeeper/

执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2014-10-21 22:05:41,856:49845:ZOO_INFO@zookeeper_init@786: Initiating client connection, host=localhost:2181 sessionTimeout=30000 watcher=0x401444 sessionId=0 sessionPasswd=context=0x402213 flags=0
2014-10-21 22:05:41,859:49845:ZOO_INFO@check_events@1703: initiated connection to server [::1:2181]
2014-10-21 22:05:41,860:49845:ZOO_INFO@check_events@1750: session establishment complete on server [::1:2181], sessionId=0x14929440e3d0027, negotiated timeout=30000
2014-10-21 22:05:41,860:49845:ZOO_DEBUG@check_events@1756: Calling a watcher for a ZOO_SESSION_EVENT and the state=ZOO_CONNECTED_STATE
2014-10-21 22:05:41,860:49845:ZOO_DEBUG@process_completions@2107: Calling a watcher for node [], type = -1 event=ZOO_SESSION_EVENT
Something happened.
type: SESSION_EVENT
state: CONNECTED_STATE
path: 
watcherCtx: hello world
[zktest_watcher_g 124] connected to zookeeper server with clientid=92650639611199527
2014-10-21 22:05:41,860:49845:ZOO_DEBUG@zoo_awexists@2835: Sending request xid=0x54473b25 for path [/xyz] to ::1:2181
2014-10-21 22:05:41,860:49845:ZOO_DEBUG@zoo_awget@2655: Sending request xid=0x54473b26 for path [/xyz] to ::1:2181
2014-10-21 22:05:41,860:49845:ZOO_DEBUG@zoo_awget_children2_@2916: Sending request xid=0x54473b27 for path [/xyz] to ::1:2181
2014-10-21 22:05:41,862:49845:ZOO_DEBUG@zookeeper_process@2264: Queueing asynchronous response
2014-10-21 22:05:41,862:49845:ZOO_DEBUG@deserialize_response@2005: Calling COMPLETION_STAT for xid=0x54473b25 failed=0 rc=0
in state completion rc = 0 data=/xyz stat:
    ctime = Tue Oct 21 21:48:42 2014
    czxid=400000052
    mtime=Tue Oct 21 21:56:06 2014
    mzxid=40000005a
    version=2   aversion=0
    ephemeralOwner = 0
2014-10-21 22:05:41,862:49845:ZOO_DEBUG@zookeeper_process@2264: Queueing asynchronous response
2014-10-21 22:05:41,862:49845:ZOO_DEBUG@deserialize_response@1992: Calling COMPLETION_DATA for xid=0x54473b26 failed=0 rc=0
in data completion [123]: rc = 0
    ctime = Tue Oct 21 21:48:42 2014
    czxid=400000052
    mtime=Tue Oct 21 21:56:06 2014
    mzxid=40000005a
    version=2   aversion=0
    ephemeralOwner = 0
2014-10-21 22:05:41,862:49845:ZOO_DEBUG@zookeeper_process@2264: Queueing asynchronous response
2014-10-21 22:05:41,862:49845:ZOO_DEBUG@deserialize_response@2029: Calling COMPLETION_STRINGLIST_STAT for xid=0x54473b27 failed=0 rc=0
in strings state completion [get children param]: rc = 0, string count 0
    ctime = Tue Oct 21 21:48:42 2014
    czxid=400000052
    mtime=Tue Oct 21 21:56:06 2014
    mzxid=40000005a
    version=2   aversion=0
    ephemeralOwner = 0

  

建议初学者使用时直接开debug,可以看清楚zookeeper的处理机制。

多线程库使用示例。该程序自己创建,读取,并删除一个节点,并能够触发watcher。

#include
#include
#include
#include<zookeeper_log.h>
#include
#include
#include
#include

static const char* state2String(int state){
if (state == 0)
return "CLOSED_STATE";
if (state == ZOO_CONNECTING_STATE)
return "CONNECTING_STATE";
if (state == ZOO_ASSOCIATING_STATE)
return "ASSOCIATING_STATE";
if (state == ZOO_CONNECTED_STATE)
return "CONNECTED_STATE";
if (state == ZOO_EXPIRED_SESSION_STATE)
return "EXPIRED_SESSION_STATE";
if (state == ZOO_AUTH_FAILED_STATE)
return "AUTH_FAILED_STATE";

return "INVALID_STATE";
}

static const char* type2String(int state){
if (state == ZOO_CREATED_EVENT)
return "CREATED_EVENT";
if (state == ZOO_DELETED_EVENT)
return "DELETED_EVENT";
if (state == ZOO_CHANGED_EVENT)
return "CHANGED_EVENT";
if (state == ZOO_CHILD_EVENT)
return "CHILD_EVENT";
if (state == ZOO_SESSION_EVENT)
return "SESSION_EVENT";
if (state == ZOO_NOTWATCHING_EVENT)
return "NOTWATCHING_EVENT";

return "UNKNOWN_EVENT_TYPE";
}

void zookeeper_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx) {
printf("\nSomething happened.\n");
printf("type: %s\n", type2String(type));
printf("state: %s\n", state2String(state));
printf("path: %s\n", path);
printf("watcherCtx: %s\n", (char *)watcherCtx);
const clientid_t *zk_clientid;
int rc;
if (type == ZOO_CREATED_EVENT) 
{
printf("[%s %d] znode %s created.\n", __FUNCTION__, __LINE__, path);

} else if (type == ZOO_DELETED_EVENT){
printf("[%s %d] znode %s deleted.\n", __FUNCTION__, __LINE__, path);

} else if (type == ZOO_CHANGED_EVENT){
printf("[%s %d] znode %s changed.\n", __FUNCTION__, __LINE__, path);

} else if(type == ZOO_CHILD_EVENT) {
printf("[%s %d] znode %s children changed.\n", __FUNCTION__, __LINE__, path);

} else if(type == ZOO_SESSION_EVENT) {
if(state == ZOO_EXPIRED_SESSION_STATE){
printf("[%s %d] zookeeper session expired\n", __FUNCTION__, __LINE__);
} else if (state == ZOO_AUTH_FAILED_STATE) {
printf("[%s %d] zookeeper session auth failed\n", __FUNCTION__, __LINE__);
} else if (state == ZOO_CONNECTING_STATE)  {
printf("[%s %d] zookeeper session is connecting\n", __FUNCTION__, __LINE__);
} else if (state == ZOO_ASSOCIATING_STATE) {
printf("[%s %d] zookeeper session is associating state\n", __FUNCTION__, __LINE__);
} else if (state == ZOO_CONNECTED_STATE){
zk_clientid = zoo_client_id(zh);
printf("[%s %d] connected to zookeeper server with clientid=%lu\n", __FUNCTION__, __LINE__, zk_clientid ->client_id);

} else if (state == ZOO_NOTWATCHING_EVENT) {
printf("[%s %d] zookeeper session remove watch\n", __FUNCTION__, __LINE__);
} else {
printf("unknown session event state = %s, path = %s, ctxt=%s\n", state2String(state), path, (char *)watcherCtx);
}

}
}

void create(zhandle_t *zkhandle,char *str) {
char path_buffer[64]="abc";
int bufferlen=sizeof(path_buffer);
printf("create node in synchronous mode-----------------------\n");
int flag = zoo_create(zkhandle, str,"syn-node", 9,
&ZOO_OPEN_ACL_UNSAFE,0,
path_buffer,bufferlen);

if (flag!=ZOK) {
printf("create syn-node failed\n");
exit(EXIT_FAILURE);
} else {
printf("created node is %s\n",path_buffer);
}
}

void exists(zhandle_t *zkhandle,char *path)
{
int flag = zoo_exists(zkhandle, path, 1, NULL);
if (flag) {
printf("%s node already exist\n", path);
} else {
printf("%s node not exist\n", path);
}
}

void getACL(zhandle_t *zkhandle,char *str)
{
struct ACL_vector acl;
struct Stat stat;
int flag = zoo_get_acl(zkhandle,str,&acl,&stat);
if (flag==ZOK && acl.count > 0) {
printf("-----------------the ACL of %s:\n------------",str);
printf("%d\n",acl.count);
printf("%d\n",acl.data->perms);
printf("%s\n",acl.data->id.scheme);
printf("%s\n",acl.data->id.id);
}
}
void delete(zhandle_t *zkhandle,char *str)
{
int flag = zoo_delete(zkhandle,str,-1);
if (flag==ZOK) {
printf("delete node %s success\n", str);
}
}

int main(int argc, const char *argv[])
{
if (argc != 2) {
printf("usage: zookeeper_m_test  server_address\n");
exit(-1);
}
const char* host = argv[1];
int timeout = 30000;
char buffer[512];
int *bufferlen;

zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
zhandle_t* zkhandle = zookeeper_init(host, zookeeper_watcher_g, timeout, 0, NULL, 0);
if (zkhandle ==NULL) {
fprintf(stderr, "Error when connecting to zookeeper servers...\n");
exit(EXIT_FAILURE);
}
create(zkhandle, "/abc");
exists(zkhandle, "/abc");
getACL(zkhandle, "/abc");
delete(zkhandle, "/abc");
while(1);
zookeeper_close(zkhandle);
}

cc -o zookeeper_m_test zookeeper_m_test.o  -I/usr/local/include/zookeeper/ -L/usr/local/lib/ -L/usr/local/lib/x86_64-linux-gnu/ -lzookeeper_mt

执行:./zookeeper_m_test localhost:2181

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2014-10-21 22:10:14,598:49903(0x7fc80aa16740):ZOO_INFO@zookeeper_init@786: Initiating client connection, host=localhost:2181 sessionTimeout=30000 watcher=0x400dfc sessionId=0 sessionPasswd=context=(nil) flags=0
2014-10-21 22:10:14,598:49903(0x7fc80aa16740):ZOO_DEBUG@start_threads@221: starting threads...
2014-10-21 22:10:14,599:49903(0x7fc8094c2700):ZOO_DEBUG@do_io@367: started IO thread
2014-10-21 22:10:14,599:49903(0x7fc8094c2700):ZOO_INFO@check_events@1703: initiated connection to server [127.0.0.1:2181]
2014-10-21 22:10:14,599:49903(0x7fc808cc1700):ZOO_DEBUG@do_completion@459: started completion thread
create node in synchronous mode-----------------------
2014-10-21 22:10:14,599:49903(0x7fc80aa16740):ZOO_DEBUG@zoo_acreate@2756: Sending request xid=0x54473c37 for path [/abc] to 127.0.0.1:2181
2014-10-21 22:10:14,604:49903(0x7fc8094c2700):ZOO_INFO@check_events@1750: session establishment complete on server [127.0.0.1:2181], sessionId=0x14929440e3d0028, negotiated timeout=30000
2014-10-21 22:10:14,604:49903(0x7fc8094c2700):ZOO_DEBUG@check_events@1756: Calling a watcher for a ZOO_SESSION_EVENT and the state=ZOO_CONNECTED_STATE
2014-10-21 22:10:14,604:49903(0x7fc808cc1700):ZOO_DEBUG@process_completions@2107: Calling a watcher for node [], type = -1 event=ZOO_SESSION_EVENT
 
Something happened.
type: SESSION_EVENT
state: CONNECTED_STATE
path: 
watcherCtx: (null)
[zookeeper_watcher_g 81] connected to zookeeper server with clientid=92650639611199528
2014-10-21 22:10:14,608:49903(0x7fc8094c2700):ZOO_DEBUG@process_sync_completion@1868: Processing sync_completion with type=6 xid=0x54473c37 rc=0
created node is /abc
2014-10-21 22:10:14,608:49903(0x7fc80aa16740):ZOO_DEBUG@zoo_awexists@2835: Sending request xid=0x54473c38 for path [/abc] to 127.0.0.1:2181
2014-10-21 22:10:14,609:49903(0x7fc8094c2700):ZOO_DEBUG@process_sync_completion@1868: Processing sync_completion with type=1 xid=0x54473c38 rc=0
/abc node not exist
2014-10-21 22:10:14,609:49903(0x7fc80aa16740):ZOO_DEBUG@zoo_aget_acl@2989: Sending request xid=0x54473c39 for path [/abc] to 127.0.0.1:2181
2014-10-21 22:10:14,611:49903(0x7fc8094c2700):ZOO_DEBUG@process_sync_completion@1868: Processing sync_completion with type=5 xid=0x54473c39 rc=0
-----------------the ACL of /abc:
------------1
31
world
anyone
2014-10-21 22:10:14,611:49903(0x7fc80aa16740):ZOO_DEBUG@zoo_adelete@2796: Sending request xid=0x54473c3a for path [/abc] to 127.0.0.1:2181
2014-10-21 22:10:14,613:49903(0x7fc8094c2700):ZOO_DEBUG@zookeeper_process@2193: Processing WATCHER_EVENT
2014-10-21 22:10:14,613:49903(0x7fc808cc1700):ZOO_DEBUG@process_completions@2107: Calling a watcher for node [/abc], type = -1 event=ZOO_DELETED_EVENT
 
Something happened.
type: DELETED_EVENT
state: CONNECTED_STATE
path: /abc
watcherCtx: (null)
[zookeeper_watcher_g 58] znode /abc deleted.
2014-10-21 22:10:14,613:49903(0x7fc8094c2700):ZOO_DEBUG@process_sync_completion@1868: Processing sync_completion with type=0 xid=0x54473c3a rc=0
delete node /abc success

  很明显,多线程库使用起来更方便。

更多API使用详细可参考以下:

参考:

http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html#C+Binding

单线程与多线程的不同

你说的那些,都是多进程,你可以理解为一个应用程序(软件)是一个进程,线程是在进程中的。一个进程可以有一个或多个线程,看起来就像某音频播放软件,一边在显示歌词、一边在显示音频柱、一边在放歌。

单线程与多线程的优缺点是什

  单线程就是进程只有一个线程
  多线程就是进程有多个线程

  多线程处理的优点

  同步应用程序的开发比较容易,但由于需要在上一个任务完成后才能开始新的任务,所以其效率通常比多线程应用程序低。如果完成同步任务所用的时间比预计时间长,应用程序可能会不响应。多线程处理可以同时运行多个过程。例如,文字处理器应用程序在您处理文档的同时,可以检查拼写(作为单独的任务)。由于多线程应用程序将程序划分成独立的任务,因此可以在以下方面显著提高性能:
  多线程技术使程序的响应速度更快,因为用户界面可以在进行其他工作的同时一直处于活动状态。
  当前没有进行处理的任务可以将处理器时间让给其他任务。
  占用大量处理时间的任务可以定期将处理器时间让给其他任务。
  可以随时停止任务。
  可以分别设置各个任务的优先级以优化性能。

  是否需要创建多线程应用程序取决于多个因素。在以下情况下,最适合采用多线程处理:
  耗时或大量占用处理器的任务阻塞用户界面操作。
  各个任务必须等待外部资源(如远程文件或 Internet 连接)。

  例如,用于跟踪 Web 页上的链接并下载满足特定条件的文件的 Internet 应用程序“robot”。这种应用程序可以依次同步下载各个文件,也可以使用多线程同时下载多个文件。多线程方法比同步方法的效率高很多,因为即使在某些线程中远程 Web 服务器的响应非常慢,也可以下载文件。
  cache.baidu.com/...aidu#0

  下面是多线程的例子
  还在Dos时代,人们就在寻求一种多任务的实现。于是出现了TSR类型的后台驻留程序,比较有代表性的有Side Kick、Vsafe等优秀的TSR程序,这类程序的出现和应用确实给用户使用计算机带来了极大的方便,比如Side Kick,我们编程可以在不用进编辑程序的状态下,一边编辑源程序,一边编译运行,非常方便。但是,Dos单任务操作系统的致命缺陷注定了在Dos下不可能开发出真正的多任务程序。进入Windows3.1时代,这种情况依然没有根本的改变,一次应用只能做一件事。比如数据库查询,除非应用编得很好,在查询期间整个系统将不响应用户的输入。
  进入了Windows NT和Windows 9x时代,情况就有了彻底的改观,操作系统从真正意义上实现了多任务(严格地说,Win9x还算不上)。一个应用程序,在需要的时候可以有许多个执行线程,每个线程就是一个小的执行程序,操作系统自动使各个线程共享CPU资源,确保任一线程都不能使系统死锁。这样,在编程的时候,可以把费时间的任务移到后台,在前台用另一个线程接受用户的输入。对那些对实时性要求比较高的编程任务,如网络客户服务、串行通信等应用时,多线程的实现无疑大大地增强了程序的可用性和稳固性。

zookeeper的c API 单线程与多线程问题 cli_st和cli_mt的更多相关文章

  1. JavaScript是单线程还是多线程(转)

    多线程要考虑线程之间的资源抢占,死锁,冲突之类一系列问题.JavaScript作为一门客户端脚本,貌似没有多线程的一些列问题.那么JavaScript是单线程还是多线程?通过查资料总结了JavaScr ...

  2. java归并排序,单线程vs多线程

    一.什么是归并排序 归并排序又称合并排序,它是成功应用分治技术的一个完美例子.对于一个需要排序的数组A[0..n-1],归并排序把它一分为二:A[0..n/2-1]和A[n/2..n-1],并对每个子 ...

  3. python单线程,多线程和协程速度对比

    在某些应用场景下,想要提高python的并发能力,可以使用多线程,或者协程.比如网络爬虫,数据库操作等一些IO密集型的操作.下面对比python单线程,多线程和协程在网络爬虫场景下的速度. 一,单线程 ...

  4. Python-爬取校花网视频(单线程和多线程版本)

    一.参考文章 python爬虫爬取校花网视频,单线程爬取 爬虫----爬取校花网视频,包含多线程版本 上述两篇文章都是对校花网视频的爬取,由于时间相隔很久了,校花网上的一些视频已经不存在了,因此上述文 ...

  5. Python-爬取妹子图(单线程和多线程版本)

    一.参考文章 Python爬虫之——爬取妹子图片 上述文章中的代码讲述的非常清楚,我的基本能思路也是这样,本篇文章中的代码仅仅做了一些异常处理和一些日志显示优化工作,写此文章主要是当做笔记,方便以后查 ...

  6. Linux -- 基于zookeeper的java api(二)

    Linux -- 基于zookeeper的java api(二) 写一个关于基于集群的zookeeper的自定义实现HA 基于客户端和监控器:使用监控的方法查看每个注册过的节点的状态来做出操作. Wa ...

  7. Linux -- 基于zookeeper的java api(一)

    Linux -- 基于zookeeper的java api 首先启动你所有的 zkService.sh 查看状态:检查是否启动正确 [root@hu-hadoop2 ~]# zkServer.sh s ...

  8. ZooKeeper客户端原生API的使用以及ZkClient第三方API的使用

    这两部分内容的介绍主要讲的是节点及节点内容和子节点的操作,并且讲解的节点的事件监听以及ACL授权 ZooKeeper客户端原生API的使用 百度网盘地址: http://pan.baidu.com/s ...

  9. 面试之二:Redis是单线程还是多线程?以及处理模型。

      Redis是单线程还是多线程?以及处理模型. 线程:单线程 处理模型:参考书<Redis 设计与实现>P151-152 ![](https://ws1.sinaimg.cn/large ...

随机推荐

  1. 【Head First Servlets and JSP】笔记 26: web 应用部署

    物理目录结构与虚拟目录结构的差异 WAR 实际上就是 JAR 什么东西应该放在 WEB-INF 文件夹下? <mime-mapping> 相关 <env-entry> 相关 [ ...

  2. JAVA学习笔记之图解JAVA参数传递

    今天做项目,发现了一个问题,当String作为参数传递的时候,在函数内部改变值对外部的变量值无影响,如下代码: public static void main(String[] args) { Str ...

  3. nginx简介及优点总结

    简介:nginx是web服务器,由C语言开发,基于事件驱动能处理百万级别的tcp连接,高度模块化的设计和自由的许可证使得扩展其功能的模块层出不穷, 跨平台,可使用当前操作系统特有的一些高效API来提高 ...

  4. mysql5.6备份

    备份之前: 最初的二进制信息: mysql> show master logs; +------------------+-----------+ | Log_name | File_size ...

  5. 20145313张雪纯 《Java程序设计》第9周学习总结

    20145313张雪纯 <Java程序设计>第9周学习总结 教材学习内容总结 JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作,开发人员无需接 ...

  6. JVM反调调用优化,导致发生大量异常时log4j2线程阻塞

    背景 在使用log4j2打日志时,当发生大量异常时,造成大量线程block问题的问题. 一个关于log4j2的高并发问题:https://blog.fliaping.com/a-high-concur ...

  7. MySQL日常维护

    删除MySQL 账号 use mysql delete from user where user='xiewenming'; 授权账号密码 GRANT SELECT,INSERT,UPDATE,DEL ...

  8. LeetCode——Unique Binary Search Trees

    Question Given n, how many structurally unique BST's (binary search trees) that store values 1...n? ...

  9. layui和bootstrap 对比

    layui和bootstrap 对比 这两个都属于UI渲染框架. layui是国人开发的一套框架,2016年出来的,现在已更新到2.X版本了.比较新,轻量级,样式简单好看. bootstrap 相对来 ...

  10. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/usr/local/mysql/tmp/mysql.sock'

    查看是否开启服务 # ps -ef | grep mysql root 5605 5457 0 11:45 pts/2 00:00:00 grep mysql 查看my.cnf # cat /etc/ ...