首页 \ 问答 \ QThreadPool示例(QThreadPool example)

QThreadPool示例(QThreadPool example)

我正在寻找一些关于使用QThreadPool简洁示例。 这是我如何使用它:

QThreadPool *thread_pool = QThreadPool::globalInstance();
MyThread *thread = new MyThread();
thread_pool->start(thread);


class MyThread : public QRunnable {
public:
    MyThread();
    ~MyThread();
    void run();
};

void MyThread::run()
{
    qDebug() << "MyThread";
}

以上是正确的做法吗?
PS:我在参考文献中看到了waitForDone ,我什么时候应该调用waitForDone


I'm looking for some concise example on the use of QThreadPool. Here's how I used it:

QThreadPool *thread_pool = QThreadPool::globalInstance();
MyThread *thread = new MyThread();
thread_pool->start(thread);


class MyThread : public QRunnable {
public:
    MyThread();
    ~MyThread();
    void run();
};

void MyThread::run()
{
    qDebug() << "MyThread";
}

Is the above the right practice ?
PS: I saw waitForDone in the reference, when should I call waitForDone ?


原文:https://stackoverflow.com/questions/17235873
更新时间:2024-02-21 11:02

最满意答案

通过研究libmpdclient源代码,我想我可以自己回答。

超时是库设计中不可恢复的错误。 这就是mpd_recv_idle ()disable_timeout参数首先出现的原因。

期望同步空闲请求“永久”阻塞(直到MPD应答请求)。 这与我想要的不兼容,我可能不得不使用低级异步接口来实现我想要的。

这是我的解决方案(最小的错误检查)。

程序等待用户按ENTER键并在后台处理MPD空闲消息,该消息可以每200 ms中断一次。

少了什么东西:

  • 返回代码解析
  • 空闲消息响应解析

这是代码:

#include <string>
#include <stdexcept>
#include <memory>
#include <iostream>
#include <thread>
#include <chrono>

#include <netinet/in.h>
#include <netdb.h>
#include <strings.h>
#include <unistd.h>

#include <mpd/async.h>
// #include <mpd/client.h>

typedef std::unique_ptr<mpd_async, decltype(&mpd_async_free)>
mpd_async_ptr;

void
check_error (const mpd_async_ptr &c, const std::string &s)
{
  if (mpd_async_get_error (c.get ()) != MPD_ERROR_SUCCESS)
    {
      throw std::runtime_error (s);
    }
}

mpd_async_event
async_poll (const mpd_async *async, timeval *tv)
{
  int events = mpd_async_events (async);
  if (events == 0)
    {
      throw std::runtime_error ("mpd_async_events failed");
    }
  int fd = mpd_async_get_fd (async);
  fd_set rfds, wfds, efds;
  FD_ZERO(&rfds);
  FD_ZERO(&wfds);
  FD_ZERO(&efds);

  if (events & MPD_ASYNC_EVENT_READ)
    {
      FD_SET(fd, &rfds);
    }
  if (events & MPD_ASYNC_EVENT_WRITE)
    {
      FD_SET(fd, &wfds);
    }
  if (events & (MPD_ASYNC_EVENT_HUP|MPD_ASYNC_EVENT_ERROR))
    {
      FD_SET(fd, &efds);
    }

  int ret = select (fd + 1, &rfds, &wfds, &efds, tv);
  if (ret > 0)
    {
      if (!FD_ISSET(fd, &rfds))
        {
          events &= ~MPD_ASYNC_EVENT_READ;
        }
      if (!FD_ISSET(fd, &wfds))
        {
          events &= ~MPD_ASYNC_EVENT_WRITE;
        }
      if (!FD_ISSET(fd, &efds))
        {
          events &= ~(MPD_ASYNC_EVENT_HUP| MPD_ASYNC_EVENT_ERROR);
        }
      return (mpd_async_event) events;
    }
  return (mpd_async_event) 0;
}

int
socket_connect (const std::string &host, uint16_t port)
{
  int sockfd = socket (AF_INET, SOCK_STREAM, 0);
  hostent *server = gethostbyname (host.c_str ());
  sockaddr_in server_addr;
  bzero ((char *) &server_addr, sizeof (server_addr));
  server_addr.sin_family = AF_INET;
  bcopy ((char *) server->h_addr, (char *) &server_addr.sin_addr.s_addr,
         server->h_length);
  server_addr.sin_port = htons (port);
  if (::connect (sockfd, (struct sockaddr*) &server_addr,
                 sizeof (server_addr)) < 0)
    {
      throw std::string ("ERROR connecting");
    }
  return sockfd;
}

void
mpd_notify_thread_proc (bool &app_is_running)
{
  const std::string host = "127.0.0.1";
  const uint16_t port = 7701;

  auto sockfd = socket_connect (host, port);
  mpd_async_ptr async_ptr {mpd_async_new (sockfd), mpd_async_free};
  auto async = async_ptr.get ();
  if (async == nullptr)
    {
      throw std::runtime_error ("mpd_async_new failed");
    }

  while (app_is_running)
    {
      timeval tv;
      tv.tv_sec = 0;
      tv.tv_usec = 200 * 1000;
      auto events = async_poll (async, &tv);
      if (events != 0)
        {
          if (!mpd_async_io (async, (mpd_async_event) events))
            {
              throw std::runtime_error ("connection was closed");
            }

          char* line_ptr;
          while ((line_ptr = mpd_async_recv_line (async)) != nullptr)
            {
              std::cout << "recv: " << line_ptr << "\n";
              std::string line {line_ptr};
              if (line.find ("OK") == 0)
                {
                  if (!mpd_async_send_command (async, "idle", nullptr))
                    {
                      throw std::runtime_error ("mpd_async_send_command failed");
                    }
                }
            }
        }
    }
}

int
main(void)
{
  bool app_is_running = true;
  std::thread mpd_notify_thread =
    std::thread (
      [&] ()
  {
    mpd_notify_thread_proc (app_is_running);
  });


  std::string response;
  getline (std::cin, response);
  std::cout << "shutting down...\n";
  app_is_running = false;
  mpd_notify_thread.join ();
}

通过调用select ()而不使用timeval并观察关闭pipe () ,可以“尽可能快地”中断改进版本:

#include <string>
#include <stdexcept>
#include <memory>
#include <iostream>
#include <thread>
#include <chrono>

#include <netinet/in.h>
#include <netdb.h>
#include <strings.h>
#include <unistd.h>

#include <mpd/async.h>
// #include <mpd/client.h>

typedef std::unique_ptr<mpd_async, decltype(&mpd_async_free)>
mpd_async_ptr;

void
check_error (const mpd_async_ptr &c, const std::string &s)
{
  if (mpd_async_get_error (c.get ()) != MPD_ERROR_SUCCESS)
    {
      throw std::runtime_error (s);
    }
}

mpd_async_event
async_poll (const mpd_async *async, int *shutdown_fd)
{
  int events = mpd_async_events (async);
  if (events == 0)
    {
      throw std::runtime_error ("mpd_async_events failed");
    }
  int fd = mpd_async_get_fd (async);
  fd_set rfds, wfds, efds;
  FD_ZERO(&rfds);
  FD_ZERO(&wfds);
  FD_ZERO(&efds);

  if (events & MPD_ASYNC_EVENT_READ)
    {
      FD_SET(fd, &rfds);
    }
  if (events & MPD_ASYNC_EVENT_WRITE)
    {
      FD_SET(fd, &wfds);
    }
  if (events & (MPD_ASYNC_EVENT_HUP|MPD_ASYNC_EVENT_ERROR))
    {
      FD_SET(fd, &efds);
    }

  FD_SET(*shutdown_fd, &rfds);
  FD_SET(*shutdown_fd, &wfds);
  FD_SET(*shutdown_fd, &efds);

  int ret = select ((fd > *shutdown_fd ? fd : *shutdown_fd) + 1, &rfds, &wfds, &efds, NULL);
  if (ret > 0)
    {
      if (!FD_ISSET(fd, &rfds))
        {
          events &= ~MPD_ASYNC_EVENT_READ;
        }
      if (!FD_ISSET(fd, &wfds))
        {
          events &= ~MPD_ASYNC_EVENT_WRITE;
        }
      if (!FD_ISSET(fd, &efds))
        {
          events &= ~(MPD_ASYNC_EVENT_HUP| MPD_ASYNC_EVENT_ERROR);
        }
      if (FD_ISSET(*shutdown_fd, &rfds))
    {
      *shutdown_fd = 0;
    }
      if (FD_ISSET(*shutdown_fd, &wfds))
    {
      *shutdown_fd = 0;
    }
      if (FD_ISSET(*shutdown_fd, &efds))
    {
      *shutdown_fd = 0;
    }
      return (mpd_async_event) events;
    }
  return (mpd_async_event) 0;
}

int
socket_connect (const std::string &host, uint16_t port)
{
  int sockfd = socket (AF_INET, SOCK_STREAM, 0);
  hostent *server = gethostbyname (host.c_str ());
  sockaddr_in server_addr;
  bzero ((char *) &server_addr, sizeof (server_addr));
  server_addr.sin_family = AF_INET;
  bcopy ((char *) server->h_addr, (char *) &server_addr.sin_addr.s_addr,
         server->h_length);
  server_addr.sin_port = htons (port);
  if (::connect (sockfd, (struct sockaddr*) &server_addr,
                 sizeof (server_addr)) < 0)
    {
      throw std::string ("ERROR connecting");
    }
  return sockfd;
}

void
mpd_notify_thread_proc (int shutdown_fd)
{
  const std::string host = "127.0.0.1";
  const uint16_t port = 7701;

  auto sockfd = socket_connect (host, port);
  mpd_async_ptr async_ptr {mpd_async_new (sockfd), mpd_async_free};
  auto async = async_ptr.get ();
  if (async == nullptr)
    {
      throw std::runtime_error ("mpd_async_new failed");
    }

  while (shutdown_fd != 0)
    {
      auto events = async_poll (async, &shutdown_fd);
      if (shutdown_fd == 0)
    {
      break;
    }
      if (events != 0)
        {
          if (!mpd_async_io (async, (mpd_async_event) events))
            {
              throw std::runtime_error ("connection was closed");
            }

          char* line_ptr;
          while ((line_ptr = mpd_async_recv_line (async)) != nullptr)
            {
              std::cout << "recv: " << line_ptr << "\n";
              std::string line {line_ptr};
              if (line.find ("OK") == 0)
                {
                  if (!mpd_async_send_command (async, "idle", nullptr))
                    {
                      throw std::runtime_error ("mpd_async_send_command failed");
                    }
                }
            }
        }
    }
}

int
main(void)
{
  int shutdown_pipe[2];
  pipe (shutdown_pipe);
  std::thread mpd_notify_thread = std::thread ([&] ()
  {
    mpd_notify_thread_proc (shutdown_pipe[0]);
  });

  std::string response;
  getline (std::cin, response);
  std::cout << "shutting down...\n";
  close (shutdown_pipe[1]);
  mpd_notify_thread.join ();
  close (shutdown_pipe[0]);
}

如果您愿意以基于事件的样式编写代码(使用libuvuvw ),那么这是一个更好的解决方案:

#include <string>
#include <stdexcept>
#include <memory>
#include <iostream>

#include <uvw.hpp>

int
main(void)
{
  auto loop = uvw::Loop::getDefault ();
  if (loop == nullptr)
    {
      throw std::runtime_error ("loop init failed");
    }
  auto tcp = loop->resource<uvw::TcpHandle>();
  if (tcp == nullptr)
    {
      throw std::runtime_error ("tcp init failed");
    }

  tcp->once<uvw::ConnectEvent> ([] (const uvw::ConnectEvent &, uvw::TcpHandle &tcp) mutable
  {
    tcp.read ();
  });

  tcp->once<uvw::ErrorEvent> ([] (const uvw::ErrorEvent &, uvw::TcpHandle &) mutable
  {
    std::cerr << "Connection error\n";
  });

  std::string buf;
  tcp->on<uvw::DataEvent> ([&] (const uvw::DataEvent &event, uvw::TcpHandle &tcp) mutable
  {
    std::string data {event.data.get (), event.length};
    buf += data;

    std::string::size_type pos;
    while ((pos = buf.find ('\n')) != std::string::npos)
      {
    std::string line = buf.substr (0, pos);
    buf.erase (0, pos + 1);
    if (!line.compare (0, 2, "OK"))
      {
        const std::string idle = "idle\n";
        std::unique_ptr<char[]> ptr {new char[idle.size ()]};
        idle.copy (ptr.get (), idle.size ());
        tcp.write (std::move (ptr), idle.size ());
      }
    else
      {
        std::cout << line << "\n";
      }
      }
  });

  tcp->connect ("127.0.0.1", 7701);

  loop->run<uvw::Loop::Mode::DEFAULT> ();
}

From studying the libmpdclient source code I think I can answer that myself.

A timeout is an unrecoverable error in the library design. That's why the disable_timeout parameter for mpd_recv_idle () is there in the first place.

Synchronous idle requests are expected to block "forever" (until MPD answers the request). This is incompatible with what I want, I will probably have to use the low level async interface to achieve what I want.

And here is my solution (with minimal error checking).

The program waits for the user to press ENTER and processes MPD idle messages in the background which can be interrupted every 200 ms.

What's missing:

  • return code parsing
  • idle message response parsing

Here is the code:

#include <string>
#include <stdexcept>
#include <memory>
#include <iostream>
#include <thread>
#include <chrono>

#include <netinet/in.h>
#include <netdb.h>
#include <strings.h>
#include <unistd.h>

#include <mpd/async.h>
// #include <mpd/client.h>

typedef std::unique_ptr<mpd_async, decltype(&mpd_async_free)>
mpd_async_ptr;

void
check_error (const mpd_async_ptr &c, const std::string &s)
{
  if (mpd_async_get_error (c.get ()) != MPD_ERROR_SUCCESS)
    {
      throw std::runtime_error (s);
    }
}

mpd_async_event
async_poll (const mpd_async *async, timeval *tv)
{
  int events = mpd_async_events (async);
  if (events == 0)
    {
      throw std::runtime_error ("mpd_async_events failed");
    }
  int fd = mpd_async_get_fd (async);
  fd_set rfds, wfds, efds;
  FD_ZERO(&rfds);
  FD_ZERO(&wfds);
  FD_ZERO(&efds);

  if (events & MPD_ASYNC_EVENT_READ)
    {
      FD_SET(fd, &rfds);
    }
  if (events & MPD_ASYNC_EVENT_WRITE)
    {
      FD_SET(fd, &wfds);
    }
  if (events & (MPD_ASYNC_EVENT_HUP|MPD_ASYNC_EVENT_ERROR))
    {
      FD_SET(fd, &efds);
    }

  int ret = select (fd + 1, &rfds, &wfds, &efds, tv);
  if (ret > 0)
    {
      if (!FD_ISSET(fd, &rfds))
        {
          events &= ~MPD_ASYNC_EVENT_READ;
        }
      if (!FD_ISSET(fd, &wfds))
        {
          events &= ~MPD_ASYNC_EVENT_WRITE;
        }
      if (!FD_ISSET(fd, &efds))
        {
          events &= ~(MPD_ASYNC_EVENT_HUP| MPD_ASYNC_EVENT_ERROR);
        }
      return (mpd_async_event) events;
    }
  return (mpd_async_event) 0;
}

int
socket_connect (const std::string &host, uint16_t port)
{
  int sockfd = socket (AF_INET, SOCK_STREAM, 0);
  hostent *server = gethostbyname (host.c_str ());
  sockaddr_in server_addr;
  bzero ((char *) &server_addr, sizeof (server_addr));
  server_addr.sin_family = AF_INET;
  bcopy ((char *) server->h_addr, (char *) &server_addr.sin_addr.s_addr,
         server->h_length);
  server_addr.sin_port = htons (port);
  if (::connect (sockfd, (struct sockaddr*) &server_addr,
                 sizeof (server_addr)) < 0)
    {
      throw std::string ("ERROR connecting");
    }
  return sockfd;
}

void
mpd_notify_thread_proc (bool &app_is_running)
{
  const std::string host = "127.0.0.1";
  const uint16_t port = 7701;

  auto sockfd = socket_connect (host, port);
  mpd_async_ptr async_ptr {mpd_async_new (sockfd), mpd_async_free};
  auto async = async_ptr.get ();
  if (async == nullptr)
    {
      throw std::runtime_error ("mpd_async_new failed");
    }

  while (app_is_running)
    {
      timeval tv;
      tv.tv_sec = 0;
      tv.tv_usec = 200 * 1000;
      auto events = async_poll (async, &tv);
      if (events != 0)
        {
          if (!mpd_async_io (async, (mpd_async_event) events))
            {
              throw std::runtime_error ("connection was closed");
            }

          char* line_ptr;
          while ((line_ptr = mpd_async_recv_line (async)) != nullptr)
            {
              std::cout << "recv: " << line_ptr << "\n";
              std::string line {line_ptr};
              if (line.find ("OK") == 0)
                {
                  if (!mpd_async_send_command (async, "idle", nullptr))
                    {
                      throw std::runtime_error ("mpd_async_send_command failed");
                    }
                }
            }
        }
    }
}

int
main(void)
{
  bool app_is_running = true;
  std::thread mpd_notify_thread =
    std::thread (
      [&] ()
  {
    mpd_notify_thread_proc (app_is_running);
  });


  std::string response;
  getline (std::cin, response);
  std::cout << "shutting down...\n";
  app_is_running = false;
  mpd_notify_thread.join ();
}

An improved version can be interrupted "as fast as possible", by calling select () without a timeval and watching for a shutdown pipe () instead:

#include <string>
#include <stdexcept>
#include <memory>
#include <iostream>
#include <thread>
#include <chrono>

#include <netinet/in.h>
#include <netdb.h>
#include <strings.h>
#include <unistd.h>

#include <mpd/async.h>
// #include <mpd/client.h>

typedef std::unique_ptr<mpd_async, decltype(&mpd_async_free)>
mpd_async_ptr;

void
check_error (const mpd_async_ptr &c, const std::string &s)
{
  if (mpd_async_get_error (c.get ()) != MPD_ERROR_SUCCESS)
    {
      throw std::runtime_error (s);
    }
}

mpd_async_event
async_poll (const mpd_async *async, int *shutdown_fd)
{
  int events = mpd_async_events (async);
  if (events == 0)
    {
      throw std::runtime_error ("mpd_async_events failed");
    }
  int fd = mpd_async_get_fd (async);
  fd_set rfds, wfds, efds;
  FD_ZERO(&rfds);
  FD_ZERO(&wfds);
  FD_ZERO(&efds);

  if (events & MPD_ASYNC_EVENT_READ)
    {
      FD_SET(fd, &rfds);
    }
  if (events & MPD_ASYNC_EVENT_WRITE)
    {
      FD_SET(fd, &wfds);
    }
  if (events & (MPD_ASYNC_EVENT_HUP|MPD_ASYNC_EVENT_ERROR))
    {
      FD_SET(fd, &efds);
    }

  FD_SET(*shutdown_fd, &rfds);
  FD_SET(*shutdown_fd, &wfds);
  FD_SET(*shutdown_fd, &efds);

  int ret = select ((fd > *shutdown_fd ? fd : *shutdown_fd) + 1, &rfds, &wfds, &efds, NULL);
  if (ret > 0)
    {
      if (!FD_ISSET(fd, &rfds))
        {
          events &= ~MPD_ASYNC_EVENT_READ;
        }
      if (!FD_ISSET(fd, &wfds))
        {
          events &= ~MPD_ASYNC_EVENT_WRITE;
        }
      if (!FD_ISSET(fd, &efds))
        {
          events &= ~(MPD_ASYNC_EVENT_HUP| MPD_ASYNC_EVENT_ERROR);
        }
      if (FD_ISSET(*shutdown_fd, &rfds))
    {
      *shutdown_fd = 0;
    }
      if (FD_ISSET(*shutdown_fd, &wfds))
    {
      *shutdown_fd = 0;
    }
      if (FD_ISSET(*shutdown_fd, &efds))
    {
      *shutdown_fd = 0;
    }
      return (mpd_async_event) events;
    }
  return (mpd_async_event) 0;
}

int
socket_connect (const std::string &host, uint16_t port)
{
  int sockfd = socket (AF_INET, SOCK_STREAM, 0);
  hostent *server = gethostbyname (host.c_str ());
  sockaddr_in server_addr;
  bzero ((char *) &server_addr, sizeof (server_addr));
  server_addr.sin_family = AF_INET;
  bcopy ((char *) server->h_addr, (char *) &server_addr.sin_addr.s_addr,
         server->h_length);
  server_addr.sin_port = htons (port);
  if (::connect (sockfd, (struct sockaddr*) &server_addr,
                 sizeof (server_addr)) < 0)
    {
      throw std::string ("ERROR connecting");
    }
  return sockfd;
}

void
mpd_notify_thread_proc (int shutdown_fd)
{
  const std::string host = "127.0.0.1";
  const uint16_t port = 7701;

  auto sockfd = socket_connect (host, port);
  mpd_async_ptr async_ptr {mpd_async_new (sockfd), mpd_async_free};
  auto async = async_ptr.get ();
  if (async == nullptr)
    {
      throw std::runtime_error ("mpd_async_new failed");
    }

  while (shutdown_fd != 0)
    {
      auto events = async_poll (async, &shutdown_fd);
      if (shutdown_fd == 0)
    {
      break;
    }
      if (events != 0)
        {
          if (!mpd_async_io (async, (mpd_async_event) events))
            {
              throw std::runtime_error ("connection was closed");
            }

          char* line_ptr;
          while ((line_ptr = mpd_async_recv_line (async)) != nullptr)
            {
              std::cout << "recv: " << line_ptr << "\n";
              std::string line {line_ptr};
              if (line.find ("OK") == 0)
                {
                  if (!mpd_async_send_command (async, "idle", nullptr))
                    {
                      throw std::runtime_error ("mpd_async_send_command failed");
                    }
                }
            }
        }
    }
}

int
main(void)
{
  int shutdown_pipe[2];
  pipe (shutdown_pipe);
  std::thread mpd_notify_thread = std::thread ([&] ()
  {
    mpd_notify_thread_proc (shutdown_pipe[0]);
  });

  std::string response;
  getline (std::cin, response);
  std::cout << "shutting down...\n";
  close (shutdown_pipe[1]);
  mpd_notify_thread.join ();
  close (shutdown_pipe[0]);
}

An even better solution, if you're willing to write your code in an event based style (using libuv and uvw):

#include <string>
#include <stdexcept>
#include <memory>
#include <iostream>

#include <uvw.hpp>

int
main(void)
{
  auto loop = uvw::Loop::getDefault ();
  if (loop == nullptr)
    {
      throw std::runtime_error ("loop init failed");
    }
  auto tcp = loop->resource<uvw::TcpHandle>();
  if (tcp == nullptr)
    {
      throw std::runtime_error ("tcp init failed");
    }

  tcp->once<uvw::ConnectEvent> ([] (const uvw::ConnectEvent &, uvw::TcpHandle &tcp) mutable
  {
    tcp.read ();
  });

  tcp->once<uvw::ErrorEvent> ([] (const uvw::ErrorEvent &, uvw::TcpHandle &) mutable
  {
    std::cerr << "Connection error\n";
  });

  std::string buf;
  tcp->on<uvw::DataEvent> ([&] (const uvw::DataEvent &event, uvw::TcpHandle &tcp) mutable
  {
    std::string data {event.data.get (), event.length};
    buf += data;

    std::string::size_type pos;
    while ((pos = buf.find ('\n')) != std::string::npos)
      {
    std::string line = buf.substr (0, pos);
    buf.erase (0, pos + 1);
    if (!line.compare (0, 2, "OK"))
      {
        const std::string idle = "idle\n";
        std::unique_ptr<char[]> ptr {new char[idle.size ()]};
        idle.copy (ptr.get (), idle.size ());
        tcp.write (std::move (ptr), idle.size ());
      }
    else
      {
        std::cout << line << "\n";
      }
      }
  });

  tcp->connect ("127.0.0.1", 7701);

  loop->run<uvw::Loop::Mode::DEFAULT> ();
}

相关问答

更多
  • 在一些朋友的帮助下,stackoverflow和一些进一步阅读我可以解决这个问题。 这是代码 import mpd class MPDProxy: def __init__(self, host="localhost", port=6600, timeout=10): self.client = mpd.MPDClient() self.host = host self.port = port self.client.timeout ...
  • MPD可能未在您用于装入sshfs文件系统的同一用户帐户下运行。 请参阅FUSE FAQ和sshfs FAQ ,如果您对安全风险感到满意,请将user_allow_other选项和mount命令的-o allow_other选项添加。 MPD is probably not running under the same user account that you used to mount the sshfs filesystem. See the FUSE FAQ and the sshfs FAQ, t ...
  • 使用Hydra它是一个用于启动并行作业的过程管理系统。 Hydra旨在原生使用多种守护进程,如ssh,rsh,pbs,slurm和sge。 。 http://www.mpich.org/static/tarballs/3.0.2/hydra-3.0.2.tar.gz Use Hydra it is a process management system for starting parallel jobs. Hydra is designed to natively work with multiple ...
  • 在播放DASH流时,您需要创建一个DashMediaSource.Factory。 第一个参数是DashChunkSource,它读取由清单定义的媒体文件。 第二个参数是读取清单的DataSource.Factory。 所以你需要提供一个DataSource.Factory来创建一个DataSource来读取你的清单。 请参阅下面代码片段中的manifestDataSourceFactory : DashMediaSource.Factory dashMediaSourceFactory = new Das ...
  • 此错误来自运行需要某些设置的旧版MPICH。 您可以尝试升级到http://www.mpich.org上提供的更新版本(最新版本为3.0.4),您不必担心设置MPD,因为它将使用更新的流程管理器(Hydra) ) 默认。 This error comes from running an old version of MPICH that requires some setup. You might try upgrading to a much newer version (the latest is 3. ...
  • 大部分问题的原因都在错误消息中详细说明: This software does not handle incomplete presentations 。 您正在尝试验证实时流,并且此工具目前不具备该功能。 关于样本描述问题,它看起来像验证器不能识别avc3内容(即参数集在带内而不是在初始化段中)。 我会考虑这个错误,并建议你在https://github.com/Dash-Industry-Forum/Conformance-and-reference-source/issues提出问题。 The cau ...
  • 在这个例子中,你可以看到音频段的长度分别为9.98秒(duration = 9980,timescale = 1000)。 由于演示的持续时间为1分59.89秒,(持续时间=“PT0H1M59.89S”),即大约13个分段(最后一个较短)。 使用网址模板(/audio/hdworld_seg_audio$Number$.m4s)来检索每个片段(用您想要的片段编号替换$ Number $(第一个片段编号为1)。这同样适用于视频片段(除了它们是4.92每个秒,所以你会有25段) In this example, ...
  • 是的,可以用hydra替换MPD。 Hydra是MPICH已经使用了几年的发射器。 它可能不是API的直接交换,但是MPD的所有功能都应该存在,并且必须在启动之前设置守护进程等头痛。 Yes, it is possible to replace MPD with hydra. Hydra is the launcher that's been used by MPICH for a couple of years now. It probably won't be a straight swap in te ...
  • 通过研究libmpdclient源代码,我想我可以自己回答。 超时是库设计中不可恢复的错误。 这就是mpd_recv_idle ()的disable_timeout参数首先出现的原因。 期望同步空闲请求“永久”阻塞(直到MPD应答请求)。 这与我想要的不兼容,我可能不得不使用低级异步接口来实现我想要的。 这是我的解决方案(最小的错误检查)。 程序等待用户按ENTER键并在后台处理MPD空闲消息,该消息可以每200 ms中断一次。 少了什么东西: 返回代码解析 空闲消息响应解析 这是代码: #include ...
  • 经过更多搜索,我终于在musicpd论坛上发帖了 https://forum.musicpd.org/viewtopic.php?f=7&t=4034 而回应是: “MPD不记得最近加载的播放列表的名称,因此无法查询它。” After more searching, I finally posted on the musicpd forum https://forum.musicpd.org/viewtopic.php?f=7&t=4034 and the response was: "MPD does n ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。