Android 不支持 SYSV IPC (SYSV IPC)

Android 不支持 System V IPC, 即下面头文件提供的功能:

  <sys/sem.h>   /* SysV semaphores*/
  <sys/shm.h>   /* SysV shared memory segments */
  <sys/msg.h>   /* SysV message queues */
  <sys/ipc.h>   /* General IPC definitions */

Android不支持SYSV IPC的原因: 会导致全局的内核资源泄漏。例如,当一个有bug的或恶意程序退出后或普通程序被强行杀死后,没有办法自动释放Sysv信号量(在内核中分配的)。然而Android系统经常自动杀死进程,给新的进程腾出空间(Android的重要机制)。这意味着,即使程序没有bug也不是恶意代码,随时间的推移,进程经常被杀死然后重新创建,内核中用于实现SysV IPC的全局表格会被填满。这个时候,就会发生奇怪的事件并导致使用SysV IPC的程序无法运行,只有重启系统。而且考虑到可能有人会故意写恶意程序,所以Android选择不支持SysV IPC。下面提供一个导致内核资源泄漏的程序(需在Linux系统上运行)作为例证:

#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>


#define  NUM_SEMAPHORES  32
#define  MAX_FAILS       10


int  main(void)
{
    int   counter = 0;
    int   fails   = 0;
    if (counter == IPC_PRIVATE)
        counter++;
    printf( "%d (NUM_SEMAPHORES=%d)\n", counter, NUM_SEMAPHORES);
    for (;;) {
        int  ret = fork();
        int  status;
        if (ret < 0) {
            perror("fork:");
            break;
        }
        if (ret == 0) {
            /* in the child */
            ret = semget( (key_t)counter, NUM_SEMAPHORES, IPC_CREAT );
            if (ret < 0) {
                return errno;
            }
            return 0;
        }
        else {
            /* in the parent */
            ret = wait(&status);
            if (ret < 0) {
                perror("waitpid:");
                break;
            }
            if (status != 0) {
                status = WEXITSTATUS(status);
                fprintf(stderr, "child %d FAIL at counter=%d: %d\n", ret,
                                counter, status);
                if (++fails >= MAX_FAILS)
                    break;
            }
        }
        counter++;
        if ((counter % 1000) == 0) {
            printf("%d\n", counter);
        }
        if (counter == IPC_PRIVATE)
            counter++;
    }
    return 0;
}

如果上面的程序在当今典型的Linux发行版上编译运行,你会发现该程序将很快地用不同的key_t值占满内核表格,系统将会发生奇怪的事件。但某些Linux系统不一定有该问题(可运行 “ipcs -u” 命令查看内核资源表及资源分配情况)。根据我们的经验,在执行上面程序之后,任何一个程序仅仅调用了 strerror() 就会崩溃。USB子系统不断报告奇怪的错误信息到系统终端等。


你可能感兴趣的:(Android 不支持 SYSV IPC (SYSV IPC))