2012-06-26 25 views
5

Xem xét szenario sau:biến toàn cầu trong không gian tên - giá trị khác nhau về chủ đề

  • 2 khác nhau mạng cổng qua boost::asio mỗi trong chủ đề riêng của mình
  • 1 cổng được tiếp nhận và xử lý dữ liệu - class DataConnection bọc trong một std::thread
  • 1 cổng là cho gửi thống kê cũng class StatConnection bọc trong một std::thread

đối kết nối đếm (và mẩu dữ liệu nhỏ khác) ý tưởng của tôi là sử dụng một biến static bên trong một namespace như:

#include <atomic> 

namespace app { 
namespace status { 
    static std::atomic<long> counter = 0; 
} 
} 

này hoạt động tốt cho lớp DataConnection. Ở đây tôi tăng counter trong c'tor và xem giá trị gia tăng.

Nhưng counter trong lớp StatConnection của tôi luôn luôn là 0

Tại sao điều này có thể xảy ra?

Tôi đã thử một số lựa chọn thay thế:

  • trao đổi std::atomic<long> cho static volatile long: Không tạo ra một sự khác biệt.
  • sử dụng không gian tên mà không cần static từ khóa.

Sau đó, tôi đã nhận lỗi mối liên kết:

multiple definition of `app::status::searchtime' 
./src/status/Status.o:/[...]/include/status/Status.hpp:16: first defined here 
[...] 

Vậy tại sao giá trị của count khác nhau giữa các chủ đề?

+0

Huh? Thành viên tĩnh của không gian tên? Tại sao không chỉ là thành viên tĩnh của lớp? – Griwes

+0

Lớp chỉ tồn tại trong một thời gian ngắn và tăng cường :: các lớp liên quan asio được bắt đầu n-lần thông qua std :: thread. Vì vậy, tôi nghĩ rằng việc đưa nó vào một không gian tên làm cho nó riêng biệt. Nhưng một thành viên tĩnh có thể giải quyết vấn đề tôi sẽ xem xét. Tôi vẫn không chắc tại sao cách tiếp cận không gian tên không hoạt động. –

Trả lời

9

static trong phạm vi không gian tên giới thiệu liên kết nội bộ, do đó, mỗi đơn vị dịch sẽ có bản sao riêng của counter – hoàn toàn ngược lại với những gì bạn thực sự muốn!

Sử dụng extern thay vào đó, trong phần đầu:

//foo.h: 
#include <atomic> 

namespace app { 
    namespace status { 
     extern std::atomic<long> counter; 
    } 
} 

Sau đó xác định các biến trong đơn vị một dịch:

//foo.cpp: 
#include "foo.h" 

namespace app { 
    namespace status { 
     std::atomic<long> counter{0L}; 
    } 
} 
+1

để làm cho nó hoạt động với 'std :: atomic ' Tôi phải viết trong 'foo.cpp':' std :: atomic counter (0); ' –

+0

@emteh: Ah, tôi không biết liệu hàm tạo rõ ràng hay không. Tôi sẽ chỉnh sửa, cảm ơn. – ildjarn

Các vấn đề liên quan