啓動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起不來的問題。
- #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;
- }
其它進程線程通信方式:除了上面提到的信號量,進程之間常用的通信方式還有共享內存、文件、網絡通信等;所有用於進程間的通信方式均可用於線程,同時線程還可以利用共享內存空間的特點使用共享變量的方式進行通信。