Apache启动No space left on device及Linux信号量初探
问题:启动Apache时,有时候会报No space left on device错误,这个意思是说设置上空间不足了,这个空间是指Linux用来存放信号量的空间,而非磁盘空间,i结点用完时也会报No space left错误。
解决办法:使用ipcs -s命令能看到系统中所有的信号量,清除掉它们即可。可运行下面这个命令全部清除:
- for semid in `ipcs -s | cut -f2 -d" "`; do ipcrm -s $semid; done
信号量:Linux系统的信号量是用来进程间通信(IPC Inter-Process Communication)的。Linux系统的信号量有两种标准实现,分别是POSIX及System v,现在大多数Linux系统实现了两种标准。这两种标准都可用于进行或线程间的通信,只是系统调用方式略有不同。
System v信号量:System v信号量通过系统调用semget来创建,ipcs命令即是显示进行间通信用的System v类型信号量以及共享内存。由此可知,Apache在我机器上使用的进程间通信方式是System v方式,至于是否在不同Linux系统上会使用其它通信方式,则要看Apache的源代码了。因此也应该知道,上面清除信号量的命令,有可能会影响到Linux上的其它进程,因此如果系统中有其它进程也使用信号量的方式进行进程间通信,那么必须在清除时识别哪些是Apache所使用的信号量,哪些是其它进程使用的信号量。
POSIX信号量:POSIX信号量可用于线程和进程间通信,分为有名和无名两种。可简单理解为是否保存在磁盘上。有名的信号量会以文件形式保存在/dev/shm下面,因此可用于不相关的进程间的通信,无名信号量只能用于线程间和父子进程间的通信。创建无名和有名信号量的系统调用分别是:sem_init和sem_open。
问题重现:如下的C语言代码就可以使信号量满,执行后可用ipcs看到创建的值为6666的信号量,从而重现Apache起不来的问题。
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <sys/stat.h>
- static int sem_id;
- int main(int argc, char **argv)
- {
- int i;
- int k;
- int pause_time;
- char op_char = 'O';
- sem_t *mutux;
- srand((unsigned int)getpid());
- for(k=0;k<=1000;k++){
- sem_id = semget((key_t)(k), 1, 066666 | IPC_CREAT);
- printf("sem_id=%d\n",&sem_id);
- }
- return 1;
- }
其它进程线程通信方式:除了上面提到的信号量,进程之间常用的通信方式还有共享内存、文件、网络通信等;所有用于进程间的通信方式均可用于线程,同时线程还可以利用共享内存空间的特点使用共享变量的方式进行通信。