显示标签为“linux”的博文。显示所有博文
显示标签为“linux”的博文。显示所有博文

2013年5月27日星期一

一个坑:crontab中使用sudo

最近,一个进程总是无法被crontab拉起,加了日志观察后,发现这一句错误信息:
sudo: sorry, you must have a tty to run sudo

google一下发现这篇帖子:http://gcoder.blogbus.com/logs/49929050.html

解决办法为:
vi /etc/sudoers
#注释掉 Defaults    requiretty

搞定!

2013年4月1日星期一

linux64下的一个链接问题: crtbeginT.o

尝试链接一个动态库,结果crtbeginT.o这个系统库出现错误:


g++ -o ttc_api_c.o -c ttc_api_c.cpp -g -Wall -Werror -O2 -fPIC
g++ -o ttc_api_c.so -shared ttc_api_c.o libttc.pic_64.a -static
/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/4.4.6/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/crtbeginT.o: could not read symbols: Bad value
collect2: ld returned 1 exit status

百思不得其姐,还好搜索到这篇帖子:
https://bugs.launchpad.net/ubuntu/+source/gcc-4.4/+bug/640734

采用文中的办法,酱紫解决了:

cd /usr/lib/gcc/x86_64-redhat-linux/4.4.6
cp crtbeginT.o crtbeginT.orig.o
cp crtbeginS.o crtbeginT.o



2012年12月20日星期四

试验:多线程竞争写

下面一段代码将试验不同条件下多线程竞争对变量进行累加的效果:

#include <stdio.h>
#include <pthread.h>

#define MAX_NUM 5000000

int num = 0;

void* thread_func(void* param)
{
for (int i=0; i<MAX_NUM; ++i)
{
++num;
}
return NULL;
}

int main()
{
pthread_t t1, t2;
pthread_create(&t1, NULL, thread_func, NULL);
pthread_create(&t2, NULL, thread_func, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("%d\n", num);
return 1;
}

假设没有竞争,则num最终输出的结果应该是10000000

试验一:执行上面的代码输出5315953
试验二:将蓝色的这行的定义修改为:volatile int num = 0;
        执行后输出5431651。
        虽然没有得到正确的结果,但从数值上看出,volatile对数据同步还是有一些效果的。
试验三:在红色的行前增加一行代码:__sync_synchronize();
        执行后输出7443185
        试验说明,内存屏障能够进一步加快多核间的内存数据同步。
试验四:将红色的这行修改为__sync_add_and_fetch(&num, 1);
        执行后得到了正确结果10000000
        由此说明,多核条件下并发累加,只有原子操作才能得到正确的结果。volatile关键字和内存屏障都不能解决。
==============================================
进一步思考:如下是CPU的结构图
线程在操作num这个数的时候,都会把num载入自己的 L1 cache line
当CPU0上的线程1改写了num的值,L1 cache line为标示为脏。然后,CPU0上的cache line会同步到CPU 1上的cache line,然后CPU1读取数据的时候,就会是最新的数据。

如果按照这种数据同步原理,则试验一应该得到正确的结果。但为什么结果又不正确呢?

CPU, L1 CACHE, 内存,这三者之间的数据同步机制究竟是如何进行的?希望有大虾予以指教。






2012年12月19日星期三

一个失败的经验:把内存映射文件当成共享内存用

服务器开发中常常采用共享内存来存储数据,好处有:
1. 预分配空间,性能高;
2. 服务器崩溃后,共享内存的数据还在,进程重启后可快速回复服务。(这点尤其重要)

但是,共享内存也有比较麻烦的问题:
1. 增加容量很麻烦:要先dump出数据,然后删除共享内存,再重新分配,再写入;
2. local cache带来了单点问题,机器死机或者掉电后,必然丢失数据。

于是,在某次服务器开发的时候,我尝试用内存映射文件来代替共享内存。因为内存映射文件有这样一些好处:
1. 与共享内存一样,进程重启后,数据得以保留;
2. 扩容方便:如果内存允许,我映射更大的一个内存区域就好;
3. 迁移方便:停止进程,然后把映射文件复制到另一个机器,再启动进程即可。

愿望总是美好的!使用内存映射文件后,系统常常莫名其妙地IO猛烈飚高,都是映射文件惹的祸。
首先,内存映射文件分配的是虚拟内存,等到程序访问这个区域后,发现没有对应的物理内存,会引起一个缺页中断,然后操作系统从文件对应的区域中,加载4KB的数据到page cache中。
然后,如果对这一内存区域执行写操作,数据并不立即被写往磁盘,而仅仅只是把这个page标记为脏页。当整个操作系统的脏页达到一定比例后,操作系统就会把这些脏页的数据写往磁盘,由此也就引起了IO突然飚高。


因此,当采用local cache的存储方案的时候,性能是第一个考虑点,其次才是方便进程快速恢复服务。而使用内存映射文件,必然增加了系统的IO,降低了性能,这与服务器开发的目的是违背的。

2012年10月25日星期四

小记:解决mysql机器上的单CPU过高

最近某一mysql机器有告警,显示单CPU占用常常超过90%。
奇怪的是,机器上4个CPU,仅CPU 0的占用较高,而其他三个CPU很闲。

继续检查发现,CPU 0的占用高,主要都花在iowait上。
可是,即便是IO高,也应该每个CPU的IOWAIT都高,毕竟mysqld是一个多线程服务器。

为了验证这点,输入:top,按f,按j,按空格,按shift+h——查看每个线程的执行情况,并显示该线程正在哪个CPU上执行。

观察发现,mysqld的线程几乎都在cpu 0上执行,难怪CPU 0的占用高。
于是简单地写个脚本来分担CPU 0的压力:

vi set_mysqld_cpu_affinity.sh
#!/bin/bash


v_list=`ps -Lf -C mysqld h| awk '{print $4}'`
for p in $v_list
do
        taskset -cp 1,2,3 $p
done

执行后CPU的IO WAIT都变得比较平均了。