我正在尝试了解互斥锁。我正在使用三个不同的线程(即加法,乘法和除法)求解数学方程(a+b) * (c+d) / e
。首先,我已经编写了这段代码。我想到的是,添加线程应首先运行,而所有其他线程应被阻止,但它给出的是随机输出。这是我到目前为止编写的代码。
#include <iostream>
#include <pthread.h>
using std::cout, std::endl;
pthread_mutex_t mutex1;
void *Division(void *arg_div)
{
int *input =(int *)arg_div;
int result = input[0]/input[1];
cout<<"Final result"<<endl;
cout << result ;
pthread_exit(NULL);
}
void *Multiplication(void *arg_mul)
{
int *input =(int *)arg_mul;
int arg1[2];
arg1[0]=input[0]*input[1];
arg1[1]=input[2];
cout<<"Multiplication results are"<<endl;
cout<<arg1[0];
cout<<arg1[1];
pthread_exit(NULL);
}
void *Addition(void *arg_add)
{
pthread_mutex_lock(&mutex1);
cout<<"Addition Thread is acquring lock"<<endl;
int *input =(int *)arg_add;
//my critical section
int arg[3];
arg[0]=input[0]+input[1];
arg[1]=input[2]+input[3];
pthread_mutex_unlock(&mutex1);
arg[2]=input[4];
cout<<"output of add function"<<endl;
cout<<arg[0]<<endl;
cout<<arg[1]<<endl;
cout<<arg[2]<<endl;
pthread_exit(NULL);
}
int main()
{
int values[5]={6,5,4,3,2};
pthread_t add;
pthread_t multiply;
pthread_t divide;
pthread_create(&add,NULL,Addition,(void*)values);
pthread_create(&multiply,NULL,Multiplication,(void*)values);
pthread_create(÷,NULL,Division,(void*)values);
pthread_join(add,NULL);
pthread_join(multiply,NULL);
pthread_join(divide,NULL);
return 0;
}
我只希望先执行加法线程,然后执行乘法线程,然后才是除法运算。
答案 0 :(得分:1)
您的代码中有两个问题。
1)只有一个线程使用该锁。这不会影响其他任何线程,因此可以随时自由运行。
2)互斥锁用于互斥,而不是执行顺序。如果您希望一个线程先于另一个线程运行,则必须安排某种方式来实现。例如,“线程2”可以在“线程1”完成的条件下等待; “线程1”将适当地发出该信号。或者,您可以研究信号量使用的生产者/消费者模型:加法线程正在为乘法线程生成要使用的结果。
答案 1 :(得分:0)
这是使用std::thread
和条件变量的版本,而不是使用pthread
的C接口。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using std::cout, std::endl;
std::mutex m;
std::condition_variable cv_div_done, cv_mul_done, cv_add_done;
// these boolean variables are needed to detect Spurious wakeups
bool b_div_done=false, b_mul_done=false, b_add_done=false;
void Division(int *input) {
std::unique_lock lk(m); // acquire mutex lock
// wait() releases the lock until the condition is met
// and here we wait for Multiplication to be done:
cv_mul_done.wait(lk, []{ return b_mul_done; });
// here we have the mutex lock again
input[0] = input[0]/input[1];
cout<<"Final result"<<endl;
cout << input[0] << "\n";
// signal those waiting for div to be done
b_div_done = true;
cv_div_done.notify_all();
} // lock released automatically when it goes out of scope
void Multiplication(int *input) {
std::unique_lock lk(m);
cv_add_done.wait(lk, []{ return b_add_done; });
input[0]=input[0]*input[1];
input[1]=input[2];
cout<<"Multiplication results are"<<endl;
cout << input[0] << "\n";
cout << input[1] << "\n";
b_mul_done = true;
cv_mul_done.notify_all();
}
void Addition(int *input) {
std::unique_lock lk(m); // not really needed in this case
input[0]=input[0]+input[1];
input[1]=input[2]+input[3];
input[2]=input[4];
cout<<"output of add function"<<endl;
cout<<input[0]<<endl;
cout<<input[1]<<endl;
cout<<input[2]<<endl;
b_add_done = true;
cv_add_done.notify_all();
}
int main() { // (a+b) x (c+d) / e
int values[5]={6,5,4,3,2};
std::thread add(Addition, values);
std::thread mul(Multiplication, values);
std::thread div(Division, values);
/* if you'd like to run the threads detached (to not have to join them),
* you can wait for the final result here */
/*
std::unique_lock lk(m);
cv_div_done.wait(lk, []{ return b_div_done; });
*/
add.join();
mul.join();
div.join();
}
输出:
output of add function
11
7
2
Multiplication results are
77
2
Final result
38
答案 2 :(得分:0)
对于计算(a + b)x(c + d)/ e,应先加法,然后相乘,最后除法。
让我们有三个信号量,sem-add的初始值为1,sem-multiply和sem-divide的初始值为0。
三个算术函数的代码应该是
addition ()
{
P (sem-add);
...
...
V (sem-multiply);
}
multiply ()
{
P (sem-multiply);
....
....
V (sem-divide);
}
division ()
{
P (sem-divide);
....
....
V (sem-add);
}
有关更多详细信息,请参见Semaphore Basics