Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在某些情况下,ffmpeg取消缩放以初始化线程_Java_Multithreading_Ffmpeg_Wildfly - Fatal编程技术网

Java 在某些情况下,ffmpeg取消缩放以初始化线程

Java 在某些情况下,ffmpeg取消缩放以初始化线程,java,multithreading,ffmpeg,wildfly,Java,Multithreading,Ffmpeg,Wildfly,我再次发布这个问题,因为我之前发布的问题已经关闭 我在wildfly中运行了一个JAVA服务,它调用外部ffmpeg二进制文件将.au文件转换为.wav文件。正在执行的实际命令如下所示: ffmpeg -y -i INPUT.au OUTPUT.wav 它运行平稳,但由于以下错误,每隔一段时间它就会创建一个空的.wav文件: Error: ffmpeg version c6710aa Copyright (c) 2000-2017 the FFmpeg developers built wi

我再次发布这个问题,因为我之前发布的问题已经关闭

我在wildfly中运行了一个JAVA服务,它调用外部ffmpeg二进制文件将.au文件转换为.wav文件。正在执行的实际命令如下所示:

ffmpeg -y -i INPUT.au OUTPUT.wav
它运行平稳,但由于以下错误,每隔一段时间它就会创建一个空的.wav文件:

Error: ffmpeg version c6710aa Copyright (c) 2000-2017 the FFmpeg 
developers
built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
configuration: --prefix=/tmp/ffmpeg-static/target --pkg-config-flags=- 
-static --extra-cflags=-I/tmp/ffmpeg-static/target/include --extra- 
ldflags=-L/tmp/ffmpeg-static/target/lib --extra-ldexeflags=-static -- 
bindir=/tmp/ffmpeg-static/bin --enable-pic --enable-ffplay --enable- 
ffserver --enable-fontconfig --enable-frei0r --enable-gpl --enable- 
version3 --enable-libass --enable-libfribidi --enable-libfdk-aac -- 
enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb -- 
enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus -- 
enable-librtmp --enable-libsoxr --enable-libspeex --enable-libtheora - 
-enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis -- 
enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 -- 
enable-libxvid --enable-libzimg --enable-nonfree --enable-openssl
libavutil      55. 34.101 / 55. 34.101
libavcodec     57. 64.101 / 57. 64.101
libavformat    57. 56.101 / 57. 56.101
libavdevice    57.  1.100 / 57.  1.100
libavfilter     6. 65.100 /  6. 65.100
libswscale      4.  2.100 /  4.  2.100
libswresample   2.  3.100 /  2.  3.100
libpostproc    54.  1.100 / 54.  1.100

Input #0, ogg, from 'INPUT.au'
Duration: 00:00:34.08, start: 0.01500, bitrate: 15kb/s
Stream: #0.0: Audio: speex, 8000Hz, mono, s16, 15kb/s

[AVFilterGraph @ 0x43ec6e0] Error initializing threading.
[AVFilterGraph @ 0x43ec6e0] Error creating filter 'anull'
如果我尝试从命令行手动转换文件,它会工作。简短的互联网搜索()表明,这可能是由于
ffmpeg
无法创建线程供内部使用。谁能详细说明一下吗

我遇到问题的服务器的负载相对较高。我已经看到wildfly正在创建接近1800个线程

谢谢

顺便说一句,我已经设法重现了这个问题。代码如下:

SystemCommandExecutor.java

    import java.io.*;
    import java.util.List;
    public class SystemCommandExecutor {
        private List<String> commandInformation;
        private String adminPassword;
        private ThreadedStreamHandler inputStreamHandler;
        private ThreadedStreamHandler errorStreamHandler;

        public SystemCommandExecutor(final List<String> commandInformation)
        {
        if (commandInformation==null) throw new NullPointerException("The commandInformation is required.");
        this.commandInformation = commandInformation;
        this.adminPassword = null;
        }

    public int executeCommand()
            throws IOException, InterruptedException
    {
        int exitValue = -99;

        try
        {
            ProcessBuilder pb = new ProcessBuilder(commandInformation);
            Process process = pb.start();
            OutputStream stdOutput = process.getOutputStream();
            InputStream inputStream = process.getInputStream();
            InputStream errorStream = process.getErrorStream();
            inputStreamHandler = new ThreadedStreamHandler(inputStream, stdOutput, adminPassword);
            errorStreamHandler = new ThreadedStreamHandler(errorStream);
            inputStreamHandler.start();
            errorStreamHandler.start();
            exitValue = process.waitFor();
            inputStreamHandler.interrupt();
            errorStreamHandler.interrupt();
            inputStreamHandler.join();
            errorStreamHandler.join();
        }
        catch (IOException e)
        {
            throw e;
        }
        catch (InterruptedException e)
        {
            throw e;
        }
        finally
        {
            return exitValue;
        }
    }

    public StringBuilder getStandardOutputFromCommand()
    {
        return inputStreamHandler.getOutputBuffer();
    }

    public StringBuilder getStandardErrorFromCommand()
    {
        return errorStreamHandler.getOutputBuffer();
    }
}
FfmpegRunnable.java

import java.io.IOException;
import java.util.List;

public class FfmpegRunnable implements Runnable {
    private List<String> command;
    SystemCommandExecutor executor;

    public FfmpegRunnable(List<String> command) {
        this.command = command;
        this.executor = new SystemCommandExecutor(command);
    }

    @Override
    public void run() {
        try {
            int id = (int) Thread.currentThread().getId();
            int result = executor.executeCommand();
            if(result != 0) {
                StringBuilder err = executor.getStandardErrorFromCommand();
                System.out.println("[" + id + "]" + "[ERROR] " + err);
            } else {
                System.out.println("[" + id + "]" + "[SUCCESS]");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

这里40是线程数,模拟不同的用户访问系统。每隔一段时间我就会遇到上面提到的错误。

为什么要将线程id强制转换为
int
<代码>字符串dest=“/tmp/OUTPUT/OUTPUT_quot+(Math.random()*1000)+”.wav”可能比您预期的更频繁地产生名称冲突…@GyroGearless,我不明白。你是说
Math.random()*1000
可能会给我相同的数字吗?我认为这可能是真的,尽管还没有发生。问题是ffmpeg正在使用pthread在内部创建线程,有时会失败。可能您达到了线程限制,
ulimit-u
为运行服务的用户显示了什么?运行服务的机器有88个处理单元(输出
nproc
)。我已经将
ulimit-u
值增加到32768,早些时候是4096。问题仍然存在。
import java.io.IOException;
import java.util.List;

public class FfmpegRunnable implements Runnable {
    private List<String> command;
    SystemCommandExecutor executor;

    public FfmpegRunnable(List<String> command) {
        this.command = command;
        this.executor = new SystemCommandExecutor(command);
    }

    @Override
    public void run() {
        try {
            int id = (int) Thread.currentThread().getId();
            int result = executor.executeCommand();
            if(result != 0) {
                StringBuilder err = executor.getStandardErrorFromCommand();
                System.out.println("[" + id + "]" + "[ERROR] " + err);
            } else {
                System.out.println("[" + id + "]" + "[SUCCESS]");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class FfmpegMain {
    public static void main(String[] args) {
        //boolean threading = false;
        System.out.println(args[0]);
        int nrThread = Integer.parseInt(args[0]);
        boolean threading = Boolean.parseBoolean(args[1]);
        System.out.println("nrThread : " + nrThread + ", threading : " + threading);
        if(threading) {
            System.out.println("ffmpeg threading enabled");
        } else {
            System.out.println("ffmpeg threading not enabled");
        }
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(nrThread);
        for(int i=0; i<nrThread*2; i++) {
            List<String> cmd = new ArrayList<String>();
            String dest = "/tmp/OUTPUT/output_" + (Math.random()*1000) + ".wav";
            String cmdStr = "/tmp/FFMPEG/ffmpeg" + (threading ? " -threads 1 " : " ")
                    + "-y -i /tmp/input.au " + dest;
            cmd.add("/bin/sh");
            cmd.add("-c");
            cmd.add(cmdStr);

            executor.submit(new FfmpegRunnable(cmd));
        }
        executor.shutdown();
    }
}
java -jar JAR.jar 40 true