【原创】libevent使能多线程模式需要做些什么

以下内容基于 libevent-2.0.21 版本 

?


1

2

3

[root@Betty WGET]# tar zxvf libevent-2.0.21-stable.tar.gz

...

[root@Betty WGET]# cd libevent-2.0.21-stable

查看当前 config.* 文件有哪些(对于后面执行 ./configure 后新增文件) 

?


1

2

3

4

5

6

7

[root@Betty libevent-2.0.21-stable]# ll config*       

-rwxr-xr-x 1 sunfei sunfei  44826 11月 19 2012 config.guess

-rw-r--r-- 1 sunfei sunfei  11968 11月 19 2012 config.h.in

-rwxr-xr-x 1 sunfei sunfei  35454 11月 19 2012 config.sub

-rwxr-xr-x 1 sunfei sunfei 504592 11月 19 2012 configure

-rw-r--r-- 1 sunfei sunfei  21849 11月 18 2012 configure.in

[root@Betty libevent-2.0.21-stable]#

从 README 中可以看到简单几步就可以进行编译和安装 

?


1

2

3

4

5

6

7

8

9

[root@Betty libevent-2.0.21-stable]# vi README

 

0. BUILDING AND INSTALLATION (Briefly)

 

$ ./configure

$ make

$ make verify   # (optional)

$ sudo make install

...

查看 configure 配置选项 

?


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

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

[root@Betty libevent-2.0.21-stable]# ./configure --help

`configure' configures this package to adapt to many kinds of systems.

 

Usage: ./configure [OPTION]... [VAR=VALUE]...

 

To assign environment variables (e.g., CC, CFLAGS...), specify them as

VAR=VALUE.  See below for descriptions of some of the useful variables.

 

Defaults for the options are specified in brackets.

 

Configuration:

  -h, --help              display this help and exit

      --help=short        display options specific to this package

      --help=recursive    display the short help of all the included packages

  -V, --version           display version information and exit

  -q, --quiet, --silent   do not print `checking ...' messages

      --cache-file=FILE   cache test results in FILE [disabled]

  -C, --config-cache      alias for `--cache-file=config.cache'

  -n, --no-create         do not create output files

      --srcdir=DIR        find the sources in DIR [configure dir or `..']

 

Installation directories:

  --prefix=PREFIX         install architecture-independent files in PREFIX

                          [/usr/local]

  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX

                          [PREFIX]

 

By default, `make install' will install all the files in

`/usr/local/bin', `/usr/local/lib' etc.  You can specify

an installation prefix other than `/usr/local' using `--prefix',

for instance `--prefix=$HOME'.

 

For better control, use the options below.

 

Fine tuning of the installation directories:

  --bindir=DIR            user executables [EPREFIX/bin]

  --sbindir=DIR           system admin executables [EPREFIX/sbin]

  --libexecdir=DIR        program executables [EPREFIX/libexec]

  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]

  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]

  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]

  --libdir=DIR            object code libraries [EPREFIX/lib]

  --includedir=DIR        C header files [PREFIX/include]

  --oldincludedir=DIR     C header files for non-gcc [/usr/include]

  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]

  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]

  --infodir=DIR           info documentation [DATAROOTDIR/info]

  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]

  --mandir=DIR            man documentation [DATAROOTDIR/man]

  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]

  --htmldir=DIR           html documentation [DOCDIR]

  --dvidir=DIR            dvi documentation [DOCDIR]

  --pdfdir=DIR            pdf documentation [DOCDIR]

  --psdir=DIR             ps documentation [DOCDIR]

 

Program names:

  --program-prefix=PREFIX            prepend PREFIX to installed program names

  --program-suffix=SUFFIX            append SUFFIX to installed program names

  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names

 

System types:

  --build=BUILD     configure for building on BUILD [guessed]

  --host=HOST       cross-compile to build programs to run on HOST [BUILD]

 

Optional Features:

  --disable-option-checking  ignore unrecognized --enable/--with options

  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)

  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]

  --disable-dependency-tracking  speeds up one-time build

  --enable-dependency-tracking   do not reject slow dependency extractors

  --enable-gcc-warnings   enable verbose warnings with GCC

  --disable-thread-support

                          disable support for threading   去使能多线程支持(锁相关)

  --disable-malloc-replacement

                          disable support for replacing the memory mgt

                          functions

  --disable-openssl       disable support for openssl encryption

  --disable-debug-mode    disable support for running in debug mode

  --disable-libevent-install, disable installation of libevent

 

  --disable-libevent-regress, skip regress in make check

 

  --enable-function-sections, make static library allow smaller binaries with --gc-sections

 

  --enable-shared[=PKGS]  build shared libraries [default=yes]

  --enable-static[=PKGS]  build static libraries [default=yes]

  --enable-fast-install[=PKGS]

                          optimize for fast installation [default=yes]

  --disable-libtool-lock  avoid locking (might break parallel builds)

 

Optional Packages:

  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]

  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)

  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use

                          both]

  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]

  --with-sysroot=DIR Search for dependent libraries within DIR

                        (or the compiler's sysroot if not specified).

 

Some influential environment variables:

  CC          C compiler command

  CFLAGS      C compiler flags

  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a

              nonstandard directory <lib dir>

  LIBS        libraries to pass to the linker, e.g. -l<library>

  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if

              you have headers in a nonstandard directory <include dir>

  CPP         C preprocessor

 

Use these variables to override the choices made by `configure' or to help

it to find libraries and programs with nonstandard names/locations.

 

Report bugs to the package provider.

[root@Betty libevent-2.0.21-stable]#

因为我需要 libevent 支持多线程锁,只需默认配置即可 

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

[root@Betty libevent-2.0.21-stable]# ./configure

...

checking for the pthreads library -lpthreads... no                        -- 1

checking whether pthreads work without any flags... yes                   -- 2

checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE        -- 3

checking if more special flags are required for pthreads... no

checking size of pthread_t... 8

...

[root@Betty libevent-2.0.21-stable]#

 

 

[root@Betty libevent-2.0.21-stable]#

[root@Betty libevent-2.0.21-stable]# ll config*

-rwxr-xr-x 1 sunfei sunfei  44826 11月 19 2012 config.guess

-rw-r--r-- 1 root   root    12603 8月  19 14:25 config.h          -- new

-rw-r--r-- 1 sunfei sunfei  11968 11月 19 2012 config.h.in

-rw-r--r-- 1 root   root   168882 8月  19 14:25 config.log        -- new

-rwxr-xr-x 1 root   root    65544 8月  19 14:25 config.status     -- new

-rwxr-xr-x 1 sunfei sunfei  35454 11月 19 2012 config.sub

-rwxr-xr-x 1 sunfei sunfei 504592 11月 19 2012 configure

-rw-r--r-- 1 sunfei sunfei  21849 11月 18 2012 configure.in

[root@Betty libevent-2.0.21-stable]#

查看 config.log 的内容(对应 ./configure 输出的详细内容) 

?


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

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

[root@Betty libevent-2.0.21-stable]# vi config.log

This file contains any messages produced by compilers while

running configure, to aid debugging if configure makes a mistake.

 

It was created by configure, which was

generated by GNU Autoconf 2.68.  Invocation command line was

 

  $ ./configure

 

## --------- ##

## Platform. ##

## --------- ##

 

hostname = Betty

uname -m = x86_64

uname -r = 2.6.32-358.el6.x86_64

uname -s = Linux

uname -v = #1 SMP Fri Feb 22 00:31:26 UTC 2013

...

## ----------- ##

## Core tests. ##

## ----------- ##

...

configure:3214: checking for gcc

configure:3230: found /usr/bin/gcc

configure:3241: result: gcc

configure:3470: checking for C compiler version

configure:3479: gcc --version >&5

gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11)

Copyright (C) 2010 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 

configure:3490: $? = 0

configure:3479: gcc -v >&5

Using built-in specs.

Target: x86_64-redhat-linux

Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --ena

ble-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-

dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --wi

th-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux

Thread model: posix

gcc version 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)

configure:3490: $? = 0

...

configure:14625: checking for the pthreads library -lpthreads         -- 检测能否以 -lpthreads 引用 libpthreads.so 库

configure:14658: gcc -o conftest -g -O2 -Wall -fno-strict-aliasing    conftest.c -lpthreads -lrt  >&5

conftest.c: In function 'main':

conftest.c:121: warning: null argument where non-null required (argument 1)

conftest.c:122: warning: null argument where non-null required (argument 1)

conftest.c:122: warning: null argument where non-null required (argument 3)

conftest.c:120: warning: 'th' is used uninitialized in this function

/usr/bin/ld: cannot find -lpthreads                                   -- 结果发现不能

collect2: ld returned 1 exit status

configure:14658: $? = 1

configure: failed program was:

| /* confdefs.h */

| #define PACKAGE_NAME ""

| #define PACKAGE_TARNAME ""

| #define PACKAGE_VERSION ""

| #define PACKAGE_STRING ""

| #define PACKAGE_BUGREPORT ""

| #define PACKAGE_URL ""

| #define PACKAGE "libevent"

| #define VERSION "2.0.21-stable"

| #define NUMERIC_VERSION 0x02001500

| #define STDC_HEADERS 1

| #define HAVE_SYS_TYPES_H 1

| #define HAVE_SYS_STAT_H 1

| #define HAVE_STDLIB_H 1

| #define HAVE_STRING_H 1

| #define HAVE_MEMORY_H 1

| #define HAVE_STRINGS_H 1

| #define HAVE_INTTYPES_H 1

| #define HAVE_STDINT_H 1

| #define HAVE_UNISTD_H 1

| #define HAVE_DLFCN_H 1

| #define LT_OBJDIR ".libs/"

| #define HAVE_ZLIB_H 1

| #define HAVE_LIBZ 1

| #define HAVE_OPENSSL_BIO_H 1

| #define HAVE_OPENSSL 1

| #define STDC_HEADERS 1

| #define HAVE_FCNTL_H 1

| #define HAVE_STDARG_H 1

| #define HAVE_INTTYPES_H 1

| #define HAVE_STDINT_H 1

| #define HAVE_STDDEF_H 1

| #define HAVE_POLL_H 1

| #define HAVE_UNISTD_H 1

| #define HAVE_SYS_EPOLL_H 1

| #define HAVE_SYS_TIME_H 1

| #define HAVE_SYS_QUEUE_H 1

| #define HAVE_SYS_PARAM_H 1

| #define HAVE_SYS_IOCTL_H 1

| #define HAVE_SYS_SELECT_H 1

| #define HAVE_NETINET_IN_H 1

| #define HAVE_SYS_SOCKET_H 1

| #define HAVE_SYS_UIO_H 1

| #define HAVE_ARPA_INET_H 1

| #define HAVE_SYS_EVENTFD_H 1

| #define HAVE_SYS_MMAN_H 1

| #define HAVE_SYS_SENDFILE_H 1

| #define HAVE_SYS_WAIT_H 1

| #define HAVE_NETDB_H 1

| #define HAVE_SYS_STAT_H 1

| #define HAVE_SYS_SYSCTL_H 1

| #define HAVE_TAILQFOREACH 1

| #define HAVE_TIMERADD 1

| #define HAVE_TIMERCMP 1

| #define HAVE_TIMERCLEAR 1

| #define HAVE_TIMERISSET 1

| #define HAVE_DECL_CTL_KERN 1

| #define HAVE_DECL_KERN_RANDOM 1

| #define HAVE_DECL_RANDOM_UUID 1

| #define HAVE_DECL_KERN_ARND 0

| #define TIME_WITH_SYS_TIME 1

| #define HAVE_GETTIMEOFDAY 1

| #define HAVE_VASPRINTF 1

| #define HAVE_FCNTL 1

| #define HAVE_CLOCK_GETTIME 1

| #define HAVE_STRTOK_R 1

| #define HAVE_STRSEP 1

| #define HAVE_GETNAMEINFO 1

| #define HAVE_INET_NTOP 1

| #define HAVE_INET_PTON 1

| #define HAVE_SIGNAL 1

| #define HAVE_SIGACTION 1

| #define HAVE_STRTOLL 1

| #define HAVE_INET_ATON 1

| #define HAVE_PIPE 1

| #define HAVE_EVENTFD 1

| #define HAVE_SENDFILE 1

| #define HAVE_MMAP 1

| #define HAVE_SPLICE 1

| #define HAVE_GETEUID 1

| #define HAVE_GETEGID 1

| #define HAVE_GETPROTOBYNUMBER 1

| #define HAVE_SETENV 1

| #define HAVE_UNSETENV 1

| #define HAVE_PUTENV 1

| #define HAVE_SYSCTL 1

| #define HAVE_UMASK 1

| #define HAVE_GETADDRINFO 1

| #define SIZEOF_LONG 8

| #define HAVE_SETFD 1

| #define HAVE_SELECT 1

| #define HAVE_POLL 1

| #define HAVE_EPOLL_CTL 1

| #define HAVE_EPOLL 1

| #define HAVE_UINT64_T 1

| #define HAVE_UINT32_T 1

| #define HAVE_UINT16_T 1

| #define HAVE_UINT8_T 1

| #define HAVE_UINTPTR_T 1

| #define HAVE_FD_MASK 1

| #define SIZEOF_LONG_LONG 8

| #define SIZEOF_LONG 8

| #define SIZEOF_INT 4

| #define SIZEOF_SHORT 2

| #define SIZEOF_SIZE_T 8

| #define SIZEOF_VOID_P 8

| #define HAVE_STRUCT_IN6_ADDR 1

| #define HAVE_STRUCT_SOCKADDR_IN6 1

| #define HAVE_SA_FAMILY_T 1

| #define HAVE_STRUCT_ADDRINFO 1

| #define HAVE_STRUCT_SOCKADDR_STORAGE 1

| #define HAVE_STRUCT_IN6_ADDR_S6_ADDR32 1

| #define HAVE_STRUCT_IN6_ADDR_S6_ADDR16 1

| #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1

| /* end confdefs.h.  */

| #include <pthread.h>

| int

| main ()

| {

| pthread_t th; pthread_join(th, 0);

|                      pthread_attr_init(0); pthread_cleanup_push(0, 0);

|                      pthread_create(0,0,0,0); pthread_cleanup_pop(0);

|   ;

|   return 0;

| }

configure:14667: result: no

configure:14570: checking whether pthreads work without any flags             -- 检查能否无任何 flag 使用 pthreads (这里的用意不太明白)

configure:14658: gcc -o conftest -g -O2 -Wall -fno-strict-aliasing    conftest.c  -lrt  >&5

conftest.c: In function 'main':

conftest.c:121: warning: null argument where non-null required (argument 1)

conftest.c:122: warning: null argument where non-null required (argument 1)

conftest.c:122: warning: null argument where non-null required (argument 3)

conftest.c:120: warning: 'th' is used uninitialized in this function

configure:14658: $? = 0

configure:14667: result: yes

configure:14686: checking for joinable pthread attribute                     -- 检查 pthread 特性是否支持 joinable(注意,这里就变成了 pthread 而不再是 pthreads)

configure:14701: gcc -o conftest -g -O2 -Wall -fno-strict-aliasing    conftest.c  -lrt  >&5

configure:14701: $? = 0

configure:14707: result: PTHREAD_CREATE_JOINABLE

configure:14717: checking if more special flags are required for pthreads

configure:14724: result: no

configure:14813: checking size of pthread_t

configure:14818: gcc -o conftest -g -O2 -Wall -fno-strict-aliasing    conftest.c -lrt  >&5

configure:14818: $? = 0

configure:14818: ./conftest

configure:14818: $? = 0

configure:14835: result: 8

configure:15289: creating ./config.status

...

查看生成的 config.h 文件(只列出和 thread 相关内容) 

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

[root@Betty libevent-2.0.21-stable]# vi config.h

 

/* config.h.  Generated from config.h.in by configure.  */

/* config.h.in.  Generated from configure.in by autoheader.  */

...

/* Define if libevent should not be compiled with thread support */

/* #undef DISABLE_THREAD_SUPPORT */

...

/* Define if you have POSIX threads libraries and header files. */

/* #undef HAVE_PTHREAD */

/* Define if we have pthreads on this system */

#define HAVE_PTHREADS 1                                   -- 和 thread 有关的宏,只定义了这个

...

/* Define to necessary symbol if this constant uses a non-standard name on

   your system. */

/* #undef PTHREAD_CREATE_JOINABLE */

...

/* The size of `pthread_t', as computed by sizeof. */

#define SIZEOF_PTHREAD_T 8

在 libevent 源码中搜索 HAVE_PTHREADS ,结果只能找到 _EVENT_HAVE_PTHREADS 。那么两者是什么关系呢? 

要回答中问题,需要执行 make  

?


1

2

3

4

5

[root@Betty libevent-2.0.21-stable]# make

test -d include/event2 || /bin/mkdir -p include/event2

/bin/sed -f ./make-event-config.sed < config.h > include/event2/event-config.hT

mv -f include/event2/event-config.hT include/event2/event-config.h

...

从前几行的输出中,可以看到如何从 config.h 得到 event2/event-config.h 这个头文件的。 

  • 基于 make-event-config.sed 文件,对 config.h 进行 sed 替换处理后,得到 event2/event-config.hT 文件;
  • 再将 event2/event-config.hT 强制变更为(覆盖) event2/event-config.h 。

文件  make-event-config.sed 内容如下 

?


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

[root@Betty libevent-2.0.21-stable]# vi make-event-config.sed

 

# Sed script to postprocess config.h into event-config.h. -- 这里说的很清楚了,用于将 config.h 处理为 event-config.h

 

1i\                                  --指定 event-config.h 开始内容

/* event2/event-config.h\

 *\

 * This file was generated by autoconf when libevent was built, and post-\

 * processed by Libevent so that its macros would have a uniform prefix.\

 *\

 * DO NOT EDIT THIS FILE.\

 *\

 * Do not rely on macros in this file existing in later versions.\

 */\

\

#ifndef _EVENT2_EVENT_CONFIG_H_\

#define _EVENT2_EVENT_CONFIG_H_\

 

$a\

\

#endif /* event2/event-config.h */    -- 指定 event-config.h 最后内容

 

s/#define /#define _EVENT_/      -- 这里完成了 XXX 到 _EVENT_XXX 的替换

s/#undef /#undef _EVENT_/

s/#ifndef /#ifndef _EVENT_/

所以 make 之后,我们得到了如下的 event-config.h 文件 

?


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

[root@Betty libevent-2.0.21-stable]# vi include/event2/event-config.h

 

/* event2/event-config.h

 *

 * This file was generated by autoconf when libevent was built, and post-

 * processed by Libevent so that its macros would have a uniform prefix.

 *

 * DO NOT EDIT THIS FILE.

 *

 * Do not rely on macros in this file existing in later versions.

 */

 

#ifndef _EVENT2_EVENT_CONFIG_H_

#define _EVENT2_EVENT_CONFIG_H_

 

/* config.h.  Generated from config.h.in by configure.  */

/* config.h.in.  Generated from configure.in by autoheader.  */

...

/* Define if libevent should not be compiled with thread support */

/* #undef _EVENT_DISABLE_THREAD_SUPPORT */

...

/* Define if you have POSIX threads libraries and header files. */

/* #undef _EVENT_HAVE_PTHREAD */

/* Define if we have pthreads on this system */

#define _EVENT_HAVE_PTHREADS 1

...

/* Define to necessary symbol if this constant uses a non-standard name on

   your system. */

/* #undef _EVENT_PTHREAD_CREATE_JOINABLE */

...

/* The size of `pthread_t', as computed by sizeof. */

#define _EVENT_SIZEOF_PTHREAD_T 8

...

这里留个疑问: 
_EVENT_HAVE_PTHREAD 和 _EVENT_HAVE_PTHREADS 的区别是什么? 

从源码 thread.h 中可以看到,此时可以使用 evthread_use_pthreads() 函数了。 

?


1

2

3

4

5

6

7

8

9

10

11

12

#if defined(_EVENT_HAVE_PTHREADS) || defined(_EVENT_IN_DOXYGEN)

/** Sets up Libevent for use with Pthreads locking and thread ID functions.

    Unavailable if Libevent is not build for use with pthreads.  Requires

    libraries to link against Libevent_pthreads as well as Libevent.

 

 

    @return 0 on success, -1 on failure. */

int evthread_use_pthreads(void);

/** Defined if Libevent was built with support for evthread_use_pthreads() */

#define EVTHREAD_USE_PTHREADS_IMPLEMENTED 1

 

#endif

至于  evthread_use_pthreads() 函数是做什么的,如何使用,已经不是本文要说明的内容了,网上可以找到相关文章。 

时间: 2024-11-05 06:30:22

【原创】libevent使能多线程模式需要做些什么的相关文章

一个崭新的&quot;云&quot;IT时代 我们需要做些什么?

本文讲的是一个崭新的"云"IT时代 我们需要做些什么,[IT168 资讯]云计算严格意义上来说是一个新名词,它既不是一项新技术,也不是一个新概念.甚至,云计算这个词本身就是值得商榷的,云的含义绝不仅仅是针对计算,而是IT系统建设的一个总体方针和大势所趋.云代表的是一个崭新的IT时代. 早在二十一世纪初,IBM就提出过On Demand随需应变,HP也提出过Utility Computing效用计算,H3C提出了IToIP.甚至在更早的上个世纪90年代中,全球各地就出现过一批以ASP(应

网站优化没有了外链的助力 我们还能做些什么

中介交易 SEO诊断 淘宝客 云主机 技术大厅 随着百度在前几天公布了外链判断之后,相信每一位站长都能够很深刻的感受到外链之路越来越窄,那么这个时候相信很多站长都会处于一个迷茫的状态,除了每天更新完网站之后,我们还能够做些什么呢?其实在这个时候,我觉得我们更应该注重网站内部的页面优化工作,保证网站足够的受用户的喜爱,那么一个用户体验好的网站,百度也会根据用户行为的判断喜爱上你的网站,从而提升你网站的权重.排名. (一)做好营销工作的优化. 我们除了在做一些SEO优化之外,其实提升网站自身品牌价值

陈庆立:成功网站四个阶段应该做些什么

中介交易 SEO诊断 淘宝客 云主机 技术大厅 成功网站四个阶段应该做些什么?(建议新手和新站长必看),现在做一个网站已经不是什么新鲜事了,但是该做网站的还是要做.新手在建站时没有经验总是要走很多弯路根据我几年来的建站经验现和平时在网上看到的一些知识特别整理出些文给大家分享下希望能帮到新手! 一.网站准备阶段 俗话说"磨刀不误砍柴功",网站准备结段绝不可忽视!此阶段我们一定要想清楚网站面对的用户群是谁?这些用户群上网的特征是什么?这些用户都在网上习惯做些什么?想清楚以后把这些信息都记录

站长在线:建站初期我们该做些什么(五)

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 这篇文章是我们讨论这个话题的最后的一点内容了,在昨天写文章的时候,我已经提到过今天要分析的内容比前面的要多一点,希望各位站长有耐心将这些内容看完并且理会.其实我的文章的语言就非常简单,很容易明白的,呵呵! 今天我和大家一起分析最后一点,也就是第五点:网站的整体架构.首先你要清楚,你做的网站要在搜索引擎中获得好的排名,那么你就一定要对自己的网站

站长在线:建站初期我们该做些什么(四)

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 今天够倒霉的,早上上班来的时候居然把电动车钥匙掰断了,不知道是我的力量大还是那个钥匙脆弱,居然就那样断掉了,今天晚上怎么回家还没确定呢!好了闲话少说,言归正传,今天该和大家一起分析第四点了. 还是老办法,我把这五点列出来,没有看过前面三篇文章的朋友可以搜索一下.文章的题目还是这个没有变. 1.网站的定位 2.关键词的选择 3.域名的选择 4.

八百客观点:略谈CRM能为企业用户做些啥

作为企业向前发展的重要一环,客户这个链条可不能轻易断开.对于企业用户而言更是如此,客户就是我们的重要储备资源,客户关系管理得好,客户自然而然就转换成企业发展的推动力.在一种全新的企业管理模式下,CRM客户关系管理系统具有区别于其它经营管理模式独特的功能, 融合了包括市场规划.业务逻辑.管理思想以及IT.通信技术等各方面,满足不同价值客户的个性化需求,提高客户满意度和忠诚度,为企业用户实现客户价值的持续贡献. 这种着力于通过客户管理来提升企业效益的CRM系统,可以为企业用户做些啥呢?以八百客CRM

站长在线:建站初期我们该做些什么(三)

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 今天是我和大家一起探讨"建站初期我们该做些什么"这个话题的第三天了,呵呵!经过前面两天的练习,现在感觉其实写文章也并没有之前我想象的那么难了!这对于我来讲,是一种鼓励!感谢这两天以来关注我文章的朋友!可能有些朋友没有看到我之前的两篇文章,那么看到这篇文章的时候,可能你就会觉得有些陌生了,还是老样子好了,我将我讲的五点都列出

除了微博营销 我们还需要做些什么 SEO?

前几天,我曾经发过一篇文章"从明星恋爱谈微博营销交互性你都知道吗",介绍微博营销那点事儿.今天,我将告诉大家,除了微博营销,我们还需要做些什么? 做过营销的朋友想必都知道,除了所谓的网络营销,搜索引擎优化,简称SEO,大家都应该听过.如果一个网站没有做搜索引擎优化,那么网站是很难让理想客户找到您的.例如我随便举个例子.比如最近要过年了,我想给我父母买一个热疗仪,于是我就在百度搜搜"热疗仪"这一关键词.   不难发现,排在前两名的为百度竞价客户,也就是所谓的,花钱买排

Windows Live Messenger能做些什么

Windows Live Messenger(原MSN)已经被白领们广泛使用.但还有很多朋友不了够了解这款IM工具.我们看看它都能做些什么-- >和世界各地的朋友.家人和同事保持联系 ·向任何联机联系人发送即时消息.立刻知道可以与哪些朋友进行交谈. ·与一组朋友对话.最多可以邀请 20 个朋友参加对话. ·查看有关您的联系人的最新信息.单击联系人 (您的联系人是您使用即时消息与其进行交流的对象.联系人列表也称为好友列表) 的状态图标可以查看其联系人卡片 (类似于名片,联系人卡片显示联系人的显示图