我对c和c++还很陌生,所以请尝试更具体地解释我应该做什么。该程序尝试使用多线程从目录中读取文件,并将信息存储在映射中,以便以后使用。
我一直在寻找类似的职位。但是,我想不通。
在https://github.com/kaldi-asr/kaldi/issues/938中,它说:“如果您获得链接器错误,该错误涉及到std::__cxx11命名空间或标记[abi:cxx11]中的类型的符号的未定义引用,则可能表明您试图将使用_glibcxx_use_cxx11_abi宏的不同值编译的对象文件链接在一起。”
对于未定义的pthread_cancel'(添加“-pthread”标志)引用的解决方案也不起作用。
我的代码是
#include <iostream> #include <iomanip> #include <fstream> #include <vector> #include <map> #include <algorithm> #include <random> #include <unistd.h> #include <cmath> #include <stdlib.h> #include <mutex> #include <sys/wait.h> #include <filesystem> #include <string> #include <pthread.h> #define time_str(s) (s < 60 ? (to_string(s) + " second(s)") : (s < 3600 ? (to_string((s) / 60) + " minute(s)") : (to_string((s) / 3600) + " hour(s) and " + to_string(((s) % 3600) / 60) + " minute(s)"))) using namespace std; namespace fs = std::filesystem; struct MyGenom { vector<string> filepaths; map<string, string> seq; }; void check_rv(int rv) { if (rv != 0) { printf("Error: Value is %d\n", rv); exit(1); } } struct Reference_Genome { static long unsigned int idx; static map <string, string> seq; static pthread_mutex_t mtxLock; static vector <string> filepaths; static void writing(string path) { ifstream rsf(path); string line, cur_chr; while (getline(rsf, line)) { if (line.substr(0, 1) == ">") { cur_chr = line.substr(1); seq[cur_chr] = ""; } else seq[cur_chr] += line; } rsf.close(); } static void *distribution(void *var) { string path; while (idx < filepaths.size()) { check_rv(pthread_mutex_lock(&mtxLock)); path = filepaths[idx]; idx++; check_rv(pthread_mutex_unlock(&mtxLock)); writing(path); } return NULL; } Reference_Genome(string dir, unsigned int n_threads) { cout << "Reading the reference genome from \'" << dir << "\'" << endl; for (const auto &entry : fs::directory_iterator(dir)) filepaths.push_back(entry.path()); time_t t1 = time(NULL); idx = 0; // init lock int rv = pthread_mutex_init(&mtxLock, NULL); check_rv(rv); pthread_t workers[n_threads]; int rs; struct MyGenom param; for (unsigned int th = 0; th < n_threads; th++) { rs = pthread_create(&workers[th], NULL, distribution, (void *)((unsigned long)th)); check_rv(rs); } for (unsigned int th = 0; th < n_threads; th++) { rs = pthread_join(workers[th], NULL); check_rv(rs); } pthread_mutex_destroy(&mtxLock); time_t t2 = time(NULL); cout << filepaths.size() << " sequences were read in " << time_str((long) t2 - (long) t1) << ".\n----------------\n"; } }; int main(int argc, char const *argv[]) { string dir = "./data/ex_seq"; unsigned int n_threads = 5; Reference_Genome ref(dir, n_threads); cout << "chr6: " << ref.seq["chr6"] << endl; cout << "chr9: " << ref.seq["chr9"] << endl; cout << "chr13: " << ref.seq["chr13"] << endl; }
gcc版本是“线程模型:posix gcc版本9.3.0(Ubuntu 9.3.0-10Ubuntu2)”。
错误是
testSeq.cpp:97: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:98: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:99: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: /tmp/cctfwVX2.o: in function `Reference_Genome::writing(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
/testSeq.cpp:46: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:48: undefined reference to `Reference_Genome::seq[abi:cxx11]'
/usr/bin/ld: /tmp/cctfwVX2.o: in function `Reference_Genome::distribution(void*)':
testSeq.cpp:55: undefined reference to `Reference_Genome::filepaths[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:55: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:56: undefined reference to `Reference_Genome::mtxLock'
/usr/bin/ld: testSeq.cpp:57: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:57: undefined reference to `Reference_Genome::filepaths[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:58: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:58: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:59: undefined reference to `Reference_Genome::mtxLock'
/usr/bin/ld: /tmp/cctfwVX2.o: in function `Reference_Genome::Reference_Genome(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int)':
testSeq.cpp:68: undefined reference to `Reference_Genome::filepaths[abi:cxx11]'
/usr/bin/ld: testSeq.cpp:70: undefined reference to `Reference_Genome::idx'
/usr/bin/ld: testSeq.cpp:72: undefined reference to `Reference_Genome::mtxLock'
/usr/bin/ld: testSeq.cpp:85: undefined reference to `Reference_Genome::mtxLock'
/usr/bin/ld: testSeq.cpp:88: undefined reference to `Reference_Genome::filepaths[abi:cxx11]'
collect2: error: ld returned 1 exit status
在类内部声明静态变量时,还必须在类外部声明一次。在本例中,您可以将其放在C++文件的底部,或者放在
long unsigned int Reference_Genome::idx;
map <string, string> Reference_Genome::seq;
pthread_mutex_t Reference_Genome::mtxLock;
vector <string> Reference_Genome::filepaths;
其思想是,您可以将类定义放在头文件中,以便包含在多个不同的编译单元中,但是静态变量只在您选择的一个。cpp文件中定义一次。