You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker容器重启后C程序出现两个运行实例的原因求助

问题描述

编写了一个小型C程序,功能为获取用户名并打印“welcome 用户名”,通过Dockerfile将程序复制到容器中执行。首次创建并运行容器后,程序输出欢迎语后容器退出;但后续重启该容器时,出现两个程序运行实例,无法理解其中原因。

相关代码与操作步骤

C程序代码(myapp.c)

#include <stdio.h>
#include <string.h>
int main()
{
char name[30] = {0};
printf("Enter your name: ");
gets(name);
printf("welcome ");
puts(name);
return 1;
} 

Dockerfile内容

FROM ubuntu:latest
RUN apt-get update && apt-get -y install gcc
RUN mkdir /home/app/
#copy myapp.c in container
COPY . /home/app/
WORKDIR /home/app/
RUN ["gcc", "myapp.c", "-o", "myapp"]
CMD ./myapp 

执行命令与现象

首次构建并运行容器

agangopadhyay@IN-RebhCTmbk5xO:~/docker/myapp$ docker build -t myappimage:1.0 .
agangopadhyay@IN-RebhCTmbk5xO:~/docker/myapp$ docker run -it --name mycontainer myappimage:1.0
Enter your name: Amiya
welcome Amiya           

此时容器因主程序退出而停止:

agangopadhyay@IN-RebhCTmbk5xO:~/docker/myapp$ docker ps -a
CONTAINER ID   IMAGE            COMMAND                CREATED             STATUS       PORTS              NAMES
7e5b2a491353   myappimage:1.0   "/bin/sh -c ./myapp"   About an hour ago   Exited (137) 10 seconds ago mycontainer

重启容器后查看进程

agangopadhyay@IN-RebhCTmbk5xO:~/docker/myapp$ docker start mycontainer
mycontainer
agangopadhyay@IN-RebhCTmbk5xO:~/docker/myapp$ docker exec -it mycontainer /bin/bash
root@7e5b2a491353:/home/app# ps -axu | grep myapp
root         1  0.1  0.0   2800  1168 pts/0    Ss+  14:04   0:00 /bin/sh -c ./myapp
root         7  0.0  0.0   2680  1072 pts/0    S+   14:04   0:00 ./myapp
root        17  0.0  0.0   3528  1684 pts/1    S+   14:04   0:00 grep --color=auto myapp

原因分析与解决办法

核心原因

Docker的CMD指令分为shell格式和exec格式两种。你使用的CMD ./myapp属于shell格式,Docker会自动用/bin/sh -c包裹执行该命令,此时:

  • PID 1的进程是/bin/sh -c ./myapp(shell父进程)
  • shell进程会fork出子进程运行./myapp,这就是你看到的第二个进程

首次运行时加了-it参数,程序能接收输入,执行完成后./myapp进程退出,shell父进程也随之退出,容器停止。而重启容器时未加-it,./myapp会卡在等待输入的状态,shell父进程作为守护进程持续运行,因此两个进程同时存在。

解决办法

有两种方式可以避免多进程情况:

  1. 使用exec格式的CMD:直接将程序作为PID 1进程运行,无需启动shell
    CMD ["./myapp"]
    
  2. 在shell命令中使用exec:让shell进程替换自身为./myapp进程,最终PID 1就是程序本身
    CMD exec ./myapp
    

内容的提问来源于stack exchange,提问作者AmiyaG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:53:20