apache 启动时信号量不足

来源:互联网 发布:什么是嵌入式单片机 编辑:程序博客网 时间:2024/04/30 18:43

启动Apache时,有时候会报No space left on device错误,这个意思是说设置上空间不足了,这个空间是指Linux用来存放信号量的空间,而非磁盘空间,i结点用完时也会报No space left错误。

使用ipcs查看系统的信号量,发现是信号量sem已经满了

据说是如果apache没有正常Stop掉的话,它的信号量是不会自动清除的,导致其一直滞留在内存中,但是根据实际情况用正常的stop貌似也有信号量不释放的问题出现,所以对Apache的这个特性不太明白。

用以下命令清除sem信号量后,apache就可以正常启动了

ipcs -s | grep nobody | perl -lane 'print `ipcrm sem $F[1]`'

但是以后也应该慎重考虑使用kill等命令去停止Apache服务。

尽量避免出现信号量不释放的问题。


信号量: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起不来的问题。

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <unistd.h> 
  4. #include <sys/types.h> 
  5. #include <sys/ipc.h> 
  6. #include <sys/sem.h> 
  7. #include <sys/stat.h>  
  8. static int sem_id;   
  9. int main(int argc, char **argv)   
  10. {   
  11.     int i;   
  12.     int k;   
  13.     int pause_time;   
  14.     char op_char = 'O';   
  15.     sem_t *mutux;   
  16.     srand((unsigned int)getpid());   
  17.     for(k=0;k<=1000;k++){   
  18.       sem_id = semget((key_t)(k), 1, 066666 | IPC_CREAT);   
  19.       printf("sem_id=%d\n",&sem_id);   
  20.     }   
  21.     return 1;   
  22. }  

其它进程线程通信方式:除了上面提到的信号量,进程之间常用的通信方式还有共享内存、文件、网络通信等;所有用于进程间的通信方式均可用于线程,同时线程还可以利用共享内存空间的特点使用共享变量的方式进行通信。


原创粉丝点击