I have a problem about the openmp compiling.
Like the following code:
#include <iostream> #include <pthread.h> #include <omp.h> #include <semaphore.h> #include <stack> using namespace std; sem_t empty,full; stack<int> stk; void produce(int i) { { sem_wait(&empty); cout<<"produce "<<i*i<<endl; stk.push(i*i); sem_post(&full); } } void consume1(int &x) { sem_wait(&full); int data=stk.top(); stk.pop(); x=data; sem_post(&empty); } void consume2() { sem_wait(&full); int data=stk.top(); stk.pop(); cout<<"consume2 "<<data<<endl; sem_post(&empty); } int main() { sem_init(&empty,0,1); sem_init(&full,0,0); pthread_t t1,t2,t3; omp_set_num_threads(3); int TID=0; #pragma omp parallel private(TID) { TID=omp_get_thread_num(); if(TID==0) { cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl; for(int i=0;i<5;i++) produce(i); } else if(TID==1) { int x; while(true) { consume1(x); cout<<"consume1 "<<x<<endl; } } else if(TID==2) { int x; while(true) { consume1(x); cout<<"consume2 "<<x<<endl; } } } return 0; }
Firstly, I compile it using:
g++ test.cpp -fopenmp -lpthread
And, I got the right answer, there are 3 threads totally.
But, when I do the compile like this:
g++ -c test.cpp -o test.o g++ test.o -o test -fopenmp -lpthread
there is just only ONE thread.
Anyone can tell me how to compile this code correctly. Thankyou in advance.
Set the project's platform toolset (project Properties -> General -> Platform Toolset) to "LLVM (clang-cl)". Enable Clang OpenMP support by adding -Xclang -fopenmp to the compiler options in project Properties -> C/C++ -> All Options -> Additional Options.
OpenMP is a set of code transforming pragmas, i.e. they are only applied at compile time. You cannot apply code transformation to an already compiled object code (ok, you can, but it is far more involving process and outside the scope of what most compilers do these days). You need -fopenmp
during the link phase only for the compiler to automatically link the OpenMP runtime library libgomp
- it does nothing else to the object code.
On a side note, although techically correct, your code does OpenMP in a very non-OpenMP way. First, you have reimplemented the OpenMP sections
construct. The parallel region in your main
function could be rewritten in a more OpenMP way:
#pragma omp parallel sections { #pragma omp section { cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl; for(int i=0;i<5;i++) produce(i); } #pragma omp section { int x; while(true) { consume1(x); cout<<"consume1 "<<x<<endl; } } #pragma omp section { int x; while(true) { consume1(x); cout<<"consume2 "<<x<<endl; } } }
(if you get SIGILL
while running this code with more than three OpenMP threads, you have encountered a bug in GCC, that will be fixed in the upcoming release)
Second, you might want to take a look at OpenMP task
construct. With it you can queue pieces of code to be executed concurrently as tasks by any idle thread. Unfortunately it requires a compiler which supports OpenMP 3.0, which rules out MSVC++ from the equation, but only if you care about portability to Windows (and you obviously don't, because you are using POSIX threads).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With