Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.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
C++ 取消阻止调用外部进程的线程_C++_Multithreading_C++11_Blocking_Nonblocking - Fatal编程技术网

C++ 取消阻止调用外部进程的线程

C++ 取消阻止调用外部进程的线程,c++,multithreading,c++11,blocking,nonblocking,C++,Multithreading,C++11,Blocking,Nonblocking,我有以下完整的可编译示例(也可用作),它生成少量线程(echo pass)和另一个线程(echo block;sleep 1;echo unblock)。第二个是so名称,因为当我在输出中看到block时,循环只是旋转它的轮子,即使其他“pass”线程早就该完成了。我本以为它会多次输出pass,其间穿插检查(因为主线程在这一点上循环),然后在最后取消阻塞 如何获得预期的行为 我意识到这可能是使用system的一个症状,但我一直在使用它来支持多线程解决方案,因为我还没有收到一个可行的替代方案。我注

我有以下完整的可编译示例(也可用作),它生成少量线程(
echo pass
)和另一个线程(
echo block;sleep 1;echo unblock
)。第二个是so名称,因为当我在输出中看到
block
时,循环只是旋转它的轮子,即使其他“pass”线程早就该完成了。我本以为它会多次输出
pass
,其间穿插
检查
(因为主线程在这一点上循环),然后在最后
取消阻塞

如何获得预期的行为

我意识到这可能是使用
system
的一个症状,但我一直在使用它来支持多线程解决方案,因为我还没有收到一个可行的替代方案。我注意到一些我可能需要改变的事情,但我仍在研究这些解决方案。不过,它们也可能是bug的来源

// -*- compile-command: "g++ -std=c++0x main.cpp;./a.out" -*-
#include <iostream>
#include <thread>
#include <map>
#include <unistd.h>

typedef char status_t;

/**
 * I know I'm not supposed to be using system, but I don't know what
 * else to use in this context.  The program I'm starting is,
 * theoretically, arbitrary.
 *
 * @param command a shell command to run, such as "pdflatex file.tex"
 * @param running a sentinal boolean for whether this thread is still
 *                running
 * @param exit_code_buf a buffer for the exit code
 *
 * @todo use std::{atomic,future,promise} appropriately...
 */
void run(std::string command, bool *running, status_t *exit_code_buf)
{
  // TODO: add std::chrono::duration timeout
  *running = true;
  *exit_code_buf = system(command.c_str());
  *running = false;
}


class ProcessGroup
{
  std::map<std::pair<std::thread *, bool *>, status_t *> threads;
public:
  void Add(std::string);
  void Join();
};

/**
 * Starts a process in a new thread and adds it to the map
 *
 * @param command a command to start
 *
 * @todo use std::{atomic,future,promise} appropriately...
 */
void
ProcessGroup::Add(std::string command)
{
  status_t *status = new status_t(0);
  bool *running = new bool(false);
  std::thread *t = new std::thread(&run, command, running, status);
  threads.insert(std::make_pair(std::make_pair(t, running), status));
}

/**
 * Periodically checks all threads to see if they are still running.
 * If one of them is, sleep for a small amount of time and check
 * again.
 */
void
ProcessGroup::Join()
{
  bool still_running;
  do {
    still_running = false;
    for (auto it = threads.cbegin(); it != threads.cend(); ++it) {
      still_running |= *it->first.second;
    }
    std::cout << "checking" << std::endl;
    if (still_running) usleep (100000);
  } while (still_running);
}

int main()
{
  std::cout << "Program start." << std::endl;
  ProcessGroup pg;
  std::string
    block("echo block; sleep 1; echo unblock"),
    pass("echo pass");

  pg.Add(block);
  std::cout << "here" << std::endl;
  for (int i = 0; i<10; i++) {
    pg.Add(pass);
  }

  std::cout << "Joining threads..." << std::endl;
  pg.Join();
  std::cout << "Program end." << std::endl;
  return 0;
}

这与有点关系,但我想这根本不是同一个问题。这看起来很像使用
system()
的症状。很明显,当一个
system()
调用处于
sleep
状态时,所有其他
system()
调用都被阻止。除此之外,您的程序是一个名副其实的赛道-有大量的数据竞赛,访问共享内存时丝毫没有同步的迹象。但这并不是问题的直接原因。我有一种预感,即“通过”似乎是在块完成后(在控制台上)完成的,但实际上是在睡眠发生时完成的。它们可能出现在后面,因为这些行被缓冲,后来被转储。@MichaelPetch:
endl
调用
flush
。实际上,您在一个线程上写入
*并在另一个线程上从同一位置读取,这是一场竞赛。您可以在那里使用
std::atomic_标志。另外,在启动线程之前,将
*running
初始化为
true
。如前所述,
Join
中的循环可能首先运行,并在任何线程有机会设置
*running
之前得出所有线程都已完成的结论。
$ g++ -std=c++0x main.cpp; ./a.out 
Program start.
here
Joining threads...
checking
block
checking
checking
checking
checking
checking
checking
checking
checking
checking
unblock
pass
pass
checking
pass
pass
pass
pass
pass
pass
pass
pass
checking
Program end.

Compilation finished at Fri Oct  3 23:49:45