标签归档:Tips

[原] OpenSSL在多线程环境下的使用(避免core dump)

OpenSSL can safely be used in multi-threaded applications provided that at least two callback functions are set, locking_function and threadid_func.
OpenSSL 是线程安全的,前提是必须注册两个回调函数。其中根据 Openssl 的版本不同,会有不同 版本的 threadid 回调函数。
如果不注册回调函数,多线程下压力一大必挂无疑。基本都是core dump:
libcrypto.so
下面贴主要代码,如何注册使用这两个回调函数:
.h

.c
我这里用的是libuv,所以代码里是uv_mutex_t*,如果是pthreads,就换成 pthread_mutex_t*;相应的 uv_thread_self() 换成 pthread_self()

打开Trace日志,果然一堆lock的坑啊。。。。

… ssl locked: [type] 16, [file] ssl_lib.c, [line] 512
… ssl unlock: [type] 16, [file] ssl_lib.c, [line] 512
… ssl locked: [type] 2, [file] ex_data.c, [line] 304
… ssl unlock: [type] 2, [file] ex_data.c, [line] 325
… ssl locked: [type] 2, [file] ex_data.c, [line] 500
… ssl unlock: [type] 2, [file] ex_data.c, [line] 511

简单看了下OpenSSL的基本算法源码,可能OpenSSL当年实现的时候内存比较精贵,所以很多算法都是static的内存块,不停new free内存,所以多线程下必须用各种lock。
内存如此便宜的现如今,这种实现方法显然不符合多线程、高并发的潮流了。。。

参考:
http://www.openssl.org/docs/crypto/threads.html
http://blog.csdn.net/yasi_xi/article/details/19125103

[原] Nagios-xi在CentOS的安装tips (web server是nginx)

1)./fullinstall会报各种包依赖错误。(其实是 ./1-prereqs 这一步)
需要先卸载原来的mysql、php,反正哪些包依赖错误就卸掉原来的。

2)Nagios默认的httpd是apache,所以默认安装各种出错。修改 ./xi-sys.cfg

把 httpd='httpd'改成 httpd='nginx'

3)./A-subcomponents
Nagios的subcomponents里面很多install / post-install脚本还是写死的
service httpd restart,要改成 service $httpd restart
(nagioscore、nrdp),nagiosmobile是php写的安装脚本,不改没关系(不影响结果,不过会执行不下去)
反正按subcomponents的install脚本照着来,如果每个都确认解压或者复制成功,不用重头执行A-subcomponents,
直接 touch installed.subcomponents 算了

4)./B-installxi
跟上面3)的问题一样,httpd 改成 $httpd

5)./E-importnagiosql
因为apache的conf和nginx完全不同(而前面步骤Nagios装的是apache的conf),这一步需要访问
http://localhost/nagiosql/index.php 肯定出错,导致这一步出问题。
在/etc/nginx/nginx.conf内新增一行:
include /etc/nginx/conf.d/nagiosxi.conf;
在/etc/nginx/conf.d/下新建nagiosxi.conf,参照/etc/httpd/conf.d/nagiosql.conf设置:

(待续)

[转] 如何高效地编写IDL代码 Tips & Thicks

适合所有IDL使用者好好看看:
Tips & Tricks for Efficient IDL Programming
尤其是3、5、9、10条:
3、Try to avoid IF statements within loops. When an IF statement appears in the middle of a loop with each element of an array in a conditional, the loop can be eliminated most of the time by using logical array expressions.

Slow:
for i = 0L, n_elements(data)-1L do $
if (data[i] le 30) then $
data[i] = 30

Faster:
dex = where(data le 30, count)
if (count gt 0) then data[dex] = 30

Even faster:
data = ((data gt 30) * data) + ((data le 30) * 30)

Fastest:
data = data > 30

5、Access large arrays by memory order. Arrays in IDL are column-major order. The important thing to remember is that IDL indexes arrays as [column, row]. The upper left-hand element of a matrix is considered to be [0,0]. This is the format used by FORTRAN, and is traditionally associated with image processing because it keeps all the elements of a single image scanline together. In contrast C and Visual Basic use row-major order and indexes its data as [row,column].

When an array is larger than or close to the working set size (the amount of physical memory available for the process) it should be accessed in memory order, meaning access it by accessing rows first.
for x = 0, 511 do for y = 0, 511 do arr[x, y] = ….
is very inefficient because to read the first column 250,000 bytes of data must be read into physical memory. This process must be repeated for each column, requiring the entire array to be read and written almost 512 times. By exchanging the two FOR loops the computing time can be reduced by a factor of 50:
for y = 0, 511 do for x = 0, 511 do arr[x, y] = ….

9. Use of the TEMPORARY function minimizes memory use when performing operations on large arrays. TEMPORARY reassigns to a new variable the memory referred to by its argument, deleting the old variable reference in the process (though the reassignment may be to a variable that reuses the original name). Assume that A is a large array. To add 1 to each element of A this is one coding option:
A = A + l
This statement creates a new array for the result of the addition and assigns the result to A before freeing the old allocation of A. Therefore, this operation needs 2*sizeof(A) of memory to perform the operation. The statement
A = temporary(A) + 1
needs no additional space.

10. Try not to use “*” for array indexing on the left hand side of a statement. Instead, use “0.” For instance, for the array
B = intarr(200, 200, 3)
it is much slower to use the following notation
B[*,*,1] = insertData
than to use
B[0,0,1] = insertData
The first notation is inefficient because the IDL interpreter will allocate/build a 200 x 200 long integer array of subscript indexes to substitute for the wildcard token. The latter notation does not need an array of subscripts; it performs direct copy to memory. (Note that ‘insertData’ must fit in the 200 x 200 x 2 memory space that defines the borders of the subarray that starts at ‘B[0,0,1]’ in order to avoid an array-out-of-bounds error.)