C++11 std::thread join 因 system_error 异常和 Xcode 6 上的 SIGABRT 崩溃?
C++11 std::thread join crashes with system_error exception and SIGABRT on Xcode 6?
这是一个简单的线程跟踪程序。该线程仅打印前十个整数,然后打印 "thread is done" 消息。
#include <iostream>
#include <vector>
#include <numeric>
#include <thread>
void f();
int main(int argc, const char * argv[]) {
std::thread t(f);
std::cout << "Thread start" << std::endl;
t.detach();
t.join();
std::cout << "Thread end" << std::endl;
return 0;
}
void f()
{
std::vector<int> a(10);
std::iota(a.begin(), a.end(), 0);
for(const int& i : a)
{
std::cout << i << std:: endl;
}
std::cout << "Thread is done." << std::endl;
}
但是,当它运行时,t.join 在 libc ABI 的某处抛出一个 std::__1::system_error 异常,导致程序以 SIGABRT 终止:
Thread start
0
1
2
3
4
5
6
7
8
9
Thread is done.
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread::join failed: No such process
有时当它运行时,主线程中的异常发生在线程 t 运行之前(在同一个地方)(但它仍然如此):
Thread start
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread::join failed: No such process
0
1
2
3
4
5
6
7
8
9
Thread is done.
A std::thread 构造完成后开始执行。因此分离是没有必要的。
问题在于,detach and join 都有线程可连接的先决条件,并且都有 post 可连接为假的条件。这意味着一旦你在一个线程上调用一个,试图调用另一个是无效的。
其次,您看到的不同行为是由于线程和主函数的执行时间不同造成的。有时分离和连接直到线程 运行 之后才执行,有时它们在 运行 之前,以及介于两者之间的任何东西。
可能是尝试加入未启动的线程的结果。
我在为这样的线程加入数组时遇到此错误:
for (auto& th : threads) th.join();
然后我重新编写了一个 for 循环手册,没有出现任何错误:
for (i = 0; i< numthreads; i++)
threads[i] = thread(start,i+1);
我认为这是因为我这样声明数组:
std::thread threads[MAXTHREADS];
所以它试图加入我尚未开始的线程。
完整代码供参考:
#include <sched.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <thread> // std::thread
#include <mutex> // std::mutex
using namespace std;
mutex mtx; // mutex for critical section
#define MAXTHREADS 10
#define MAXTIMES 1
int data[MAXTHREADS];
int start(int id) {
int stride = 64, dummy;
mtx.lock();
for(int times = 0; times < MAXTIMES; times++) {
for (int i = 0; i < MAXTHREADS; i = i + 1) {
//dummy = data[i]; //sim a read from every slot in the array
cout << data[i] << ", ";
}
cout << endl;
}
mtx.unlock();
return 0;
}
int main()
{
std::thread threads[MAXTHREADS];
int i;
int numthreads = 6;
for(int i = 0; i < MAXTHREADS; i++)
data[i] = i;
printf("Creating %d threads\n", numthreads);
for (i = 0; i< numthreads; i++)
threads[i] = thread(start,i+1);
for (i = 0; i< numthreads; i++)
threads[i].join();
//for (auto& th : threads) th.join();
printf("All threads joined\n");
return 0;
}
这是一个简单的线程跟踪程序。该线程仅打印前十个整数,然后打印 "thread is done" 消息。
#include <iostream>
#include <vector>
#include <numeric>
#include <thread>
void f();
int main(int argc, const char * argv[]) {
std::thread t(f);
std::cout << "Thread start" << std::endl;
t.detach();
t.join();
std::cout << "Thread end" << std::endl;
return 0;
}
void f()
{
std::vector<int> a(10);
std::iota(a.begin(), a.end(), 0);
for(const int& i : a)
{
std::cout << i << std:: endl;
}
std::cout << "Thread is done." << std::endl;
}
但是,当它运行时,t.join 在 libc ABI 的某处抛出一个 std::__1::system_error 异常,导致程序以 SIGABRT 终止:
Thread start
0
1
2
3
4
5
6
7
8
9
Thread is done.
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread::join failed: No such process
有时当它运行时,主线程中的异常发生在线程 t 运行之前(在同一个地方)(但它仍然如此):
Thread start
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread::join failed: No such process
0
1
2
3
4
5
6
7
8
9
Thread is done.
A std::thread 构造完成后开始执行。因此分离是没有必要的。
问题在于,detach and join 都有线程可连接的先决条件,并且都有 post 可连接为假的条件。这意味着一旦你在一个线程上调用一个,试图调用另一个是无效的。
其次,您看到的不同行为是由于线程和主函数的执行时间不同造成的。有时分离和连接直到线程 运行 之后才执行,有时它们在 运行 之前,以及介于两者之间的任何东西。
可能是尝试加入未启动的线程的结果。
我在为这样的线程加入数组时遇到此错误:
for (auto& th : threads) th.join();
然后我重新编写了一个 for 循环手册,没有出现任何错误:
for (i = 0; i< numthreads; i++)
threads[i] = thread(start,i+1);
我认为这是因为我这样声明数组:
std::thread threads[MAXTHREADS];
所以它试图加入我尚未开始的线程。
完整代码供参考:
#include <sched.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <thread> // std::thread
#include <mutex> // std::mutex
using namespace std;
mutex mtx; // mutex for critical section
#define MAXTHREADS 10
#define MAXTIMES 1
int data[MAXTHREADS];
int start(int id) {
int stride = 64, dummy;
mtx.lock();
for(int times = 0; times < MAXTIMES; times++) {
for (int i = 0; i < MAXTHREADS; i = i + 1) {
//dummy = data[i]; //sim a read from every slot in the array
cout << data[i] << ", ";
}
cout << endl;
}
mtx.unlock();
return 0;
}
int main()
{
std::thread threads[MAXTHREADS];
int i;
int numthreads = 6;
for(int i = 0; i < MAXTHREADS; i++)
data[i] = i;
printf("Creating %d threads\n", numthreads);
for (i = 0; i< numthreads; i++)
threads[i] = thread(start,i+1);
for (i = 0; i< numthreads; i++)
threads[i].join();
//for (auto& th : threads) th.join();
printf("All threads joined\n");
return 0;
}