2013-04-05 23 views
5

Tôi đang thử nghiệm std::async cách ly trước khi sử dụng nó trong mã thực, để xác minh rằng nó hoạt động chính xác trên nền tảng của tôi (đó là ubuntu 12,10 64-bit).Là std :: async bị hỏng trong gcc 4.7 trên linux?

Nó hoạt động (hơi hiếm khi) và thường chỉ bị treo. Nếu nó làm việc cho bạn, đừng nhảy đến kết luận. Hãy thử một vài lần nữa, nó có thể sẽ treo.

Nếu tôi xóa bài kiểm tra pthread_mutex, nó không treo. Đây là mã nhỏ nhất mà tôi có thể tạo lại hang. Có một số lý do mà bạn không thể kết hợp mã pthread C với mã async C++?

#include <iostream> 
#include <pthread.h> 
#include <chrono> 
#include <future> 
#include <iomanip> 
#include <sstream> 
#include <type_traits> 

template<typename T> 
std::string format_ns(T &&value) 
{ 
    std::stringstream s; 
    if (std::is_floating_point<T>::value) 
     s << std::setprecision(3); 

    if (value >= 1000000000) 
     s << value/1000000000 << "s"; 
    else if (value >= 1000000) 
     s << value/1000000 << "ms"; 
    else if (value >= 1000) 
     s << value/1000 << "us"; 
    else 
     s << value << "ns"; 
    return s.str(); 
} 

template<typename F> 
void test(const std::string &msg, int iter, F &&lambda) 
{ 
    std::chrono::high_resolution_clock clock; 
    auto st = clock.now(); 

    int i; 
    for (i = 0; i < iter; ++i) 
     lambda(); 
    auto en = clock.now(); 
    std::chrono::nanoseconds dur = std::chrono::duration_cast< 
     std::chrono::nanoseconds>(en-st); 

    std::cout << msg << format_ns(dur.count()/i) << std::endl; 
} 

int test_pthread_mutex() 
{ 
    pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; 

    test("pthread_mutex_lock/pthread_mutex_unlock: ", 1000000000, 
    [&]() 
    { 
     pthread_mutex_lock(&m); 
     pthread_mutex_unlock(&m); 
    }); 

    pthread_mutex_destroy(&m); 

    return 0; 
} 

int test_async() 
{ 
    test("async: ", 100, 
    [&]() 
    { 
     auto asy = std::async(std::launch::async, [](){}); 
     asy.get(); 
    }); 

    return 0; 
} 

int main() 
{ 
    test_pthread_mutex(); 
    test_async(); 
} 

Đây là dòng build lệnh:

g++ -Wextra -Wall --std=c++11 -pthread mutexperf/main.cpp 

Không có tin nhắn build đầu ra.

Dưới đây là sản phẩm của g ++ -v

Using built-in specs. 
COLLECT_GCC=g++ 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper 
Target: x86_64-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.2-2ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) 
+1

Tôi có cùng trình biên dịch và thiết lập như bạn. Tôi không thể tái tạo. Mã trông đẹp. –

+0

@johan Tôi nghĩ rằng nó có thể không tái tạo. Tôi sẽ thử nó trên một số máy khác và xem điều gì xảy ra. Cảm ơn. – doug65536

Trả lời

2

Tôi đã thử trên một vài máy tính khác nhau và thấy rằng nó thực sự hoạt động tốt như @johan đã nhận xét. Tôi đã điều tra máy tôi đang sử dụng và tìm thấy bằng chứng cho thấy ổ cứng đang bắt đầu thất bại. Nó có một số lĩnh vực xấu và cũng có thể thấy dmesg báo cáo một số "cứng reset" của ổ cứng sau một đóng băng thứ 4 bất thường. Odd, tôi đã không nhìn thấy bất kỳ vấn đề trước khi tôi đăng câu hỏi. Nó có thể là một số tham nhũng tinh tế/gián đoạn khi biên dịch/liên kết hoặc có lẽ khi tải tệp thực thi.

[44242.380936] ata3.00: exception Emask 0x10 SAct 0x0 SErr 0x800000 action 0x6 frozen 
[44242.380942] ata3.00: irq_stat 0x08000000, interface fatal error 
[44242.380946] ata3: SError: { LinkSeq } 
[44242.380950] sr 2:0:0:0: CDB: 
[44242.380952] Get event status notification: 4a 01 00 00 10 00 00 00 08 00 
[44242.380965] ata3.00: cmd a0/00:00:00:08:00/00:00:00:00:00/a0 tag 0 pio 16392 in 
[44242.380965]   res 50/00:03:00:08:00/00:00:00:00:00/a0 Emask 0x10 (ATA bus error) 
[44242.380968] ata3.00: status: { DRDY } 
[44242.380974] ata3: hard resetting link 
[44242.700025] ata3: SATA link up 1.5 Gbps (SStatus 113 SControl 300) 
[44242.704849] ata3.00: configured for UDMA/100 
[44242.720055] ata3: EH complete 
[44970.117542] ata3.00: exception Emask 0x10 SAct 0x0 SErr 0x800100 action 0x6 frozen 
[44970.117547] ata3.00: irq_stat 0x08000000, interface fatal error 
[44970.117551] ata3: SError: { UnrecovData LinkSeq } 
[44970.117555] sr 2:0:0:0: CDB: 
[44970.117557] Get event status notification: 4a 01 00 00 10 00 00 00 08 00 
[44970.117570] ata3.00: cmd a0/00:00:00:08:00/00:00:00:00:00/a0 tag 0 pio 16392 in 
[44970.117570]   res 50/00:03:00:08:00/00:00:00:00:00/a0 Emask 0x10 (ATA bus error) 
[44970.117573] ata3.00: status: { DRDY } 
[44970.117579] ata3: hard resetting link 
[44970.436662] ata3: SATA link up 1.5 Gbps (SStatus 113 SControl 300) 
[44970.443159] ata3.00: configured for UDMA/100 
[44970.456639] ata3: EH complete 

Nhờ bất kỳ ai dành thời gian xem xét vấn đề của tôi!

0

Bạn đã cố gắng sao chép các mutex chứ không phải vượt qua bằng cách tham khảo trong lambda?

int test_pthread_mutex() 
{ 
    pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; 

    test("pthread_mutex_lock/pthread_mutex_unlock: ", 1000000000, 
    [=]() 
    { 
     pthread_mutex_lock(&m); 
     pthread_mutex_unlock(&m); 
    }); 

    pthread_mutex_destroy(&m); 

    return 0; 
} 
Các vấn đề liên quan