【问题标题】:Threads in for loop not working correctlyfor 循环中的线程无法正常工作
【发布时间】:2017-08-16 20:11:04
【问题描述】:

我想制作一个程序,从数据库中获取 id 并为每个 id 创建一个具有相同函数的线程。它可以工作,但是当我向函数添加一个 while 循环时,它只会挂在那里并且没有得到下一个 id。

我的代码是:

void foo(char* i) {
    while(1){
        std::cout << i;
    }
}

void makeThreads()
{
    int i;

    MYSQL *sqlhnd = mysql_init(NULL);
    mysql_real_connect(sqlhnd, "127.0.0.1", "root", "h0flcepqE", "Blazor", 3306, NULL, 0);

    mysql_query(sqlhnd, "SELECT id FROM `notifications`");
    MYSQL_RES *confres = mysql_store_result(sqlhnd);
    int totalrows = mysql_num_rows(confres);
    int numfields = mysql_num_fields(confres);
    MYSQL_FIELD *mfield;
    MYSQL_ROW row;

    while((row = mysql_fetch_row(confres)))
    {
        for(i = 0; i < numfields; i++)
        {

            printf("%s", row[i]);

            std::thread t(foo, row[i]);


            t.join();


        }
    }

}

int main()
{
    makeThreads();
    return 0;
}

输出是:

111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

谢谢

【问题讨论】:

  • 线程永远不会加入,因为它的执行永远不会结束。问题出在 imo 上。
  • 您知道线程上的join 调用什么(例如在t.join(); 中)吗?它挂起阻塞线程,并等待joined 线程(t)终止。而且,正如所写,它永远不会。如果您阅读 std::thread::join 的文档,或者在调试器中单步调试您的代码,这样的功能就会很明显。
  • 除了挂起之外,您对循环 while(1){ std::cout &lt;&lt; i; } 的期望是什么,或者您期望的输出是什么?
  • 正如@Stephan 所说:这对 CPU 来说太残忍了!你应该为此被罚款。
  • 对,所以代码不会被执行,因为线程没有被终止。有什么方法可以创建一个新线程并将其加入 for- 循环?

标签: c++ multithreading while-loop


【解决方案1】:

有问题的for 循环当前创建一个thread 对象和一个线程。时期。 joining 通过强制主线程等待线程运行完成以某种方式隐藏了这个问题。线程不能是另一个问题。

创建一个线程并立即joining 会强制您的程序按顺序运行,从而破坏了使用线程的意义。不加入thread 将导致Bad,因为thread 对象将在循环结束时被销毁并且thread 尚未分离。 Destroying an undetached thread is bad. std::terminate 几乎就像它听起来的那样:它追捕并杀死了莎拉康纳。只是在开玩笑。它以刽子手斧头的所有微妙之处结束您的程序。

您可以通过调用 detach 手动分离线程,但这是一个非常非常糟糕的主意,因为您失去了对线程的控制,并且您的程序将在线程仍在运行时退出。

您需要在生成它们的循环之后存储这些线程和join 它们。

这是一个简单的方法:

std::vector<std::thread> threads;
for(i = 0; i < numfields; i++)
{
    std::cout << row[i];
    threads.push_back(std::thread(foo, row[i]));
}
for (std::thread & t: threads)
{
    t.join();
}

现在numfields 线程将永远运行,我相信你可以自己解决这个问题。

【讨论】:

    【解决方案2】:

    t.join(); 表示程序在这里等待线程 t 完成。 自:

    • t 执行 foo
    • foo 永远不会结束,因为 while true

    那么:你永远不会在加入后执行指令

    所以你有不间断的 111111

    【讨论】:

      猜你喜欢
      • 2013-08-17
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-01
      • 2021-09-26
      • 1970-01-01
      • 2013-06-26
      相关资源
      最近更新 更多