Mutex 没有按预期工作
Mutex does not work as expected
我在继承 类 中使用了互斥锁,但它似乎无法像我预期的那样在线程中工作。请看下面的代码:
#include <iostream>
#include <cstdlib>
#include <pthread.h>
// mutex::lock/unlock
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::thread
#include <mutex> // std::mutex
typedef unsigned int UINT32t;
typedef int INT32t;
using namespace std;
class Abstract {
protected:
std::mutex mtx;
};
class Derived: public Abstract
{
public:
void* write( void* result)
{
UINT32t error[1];
UINT32t data = 34;
INT32t length = 0;
static INT32t counter = 0;
cout << "\t before Locking ..." << " in thread" << endl;
mtx.lock();
//critical section
cout << "\t After Create " << ++ counter << " device in thread" << endl;
std::this_thread::sleep_for(1s);
mtx.unlock();
cout << "\t deallocated " << counter << " device in thread" << endl;
pthread_exit(result);
}
};
void* threadTest1( void* result)
{
Derived dev;
dev.write(nullptr);
}
int main()
{
unsigned char byData[1024] = {0};
ssize_t len;
void *status = 0, *status2 = 0;
int result = 0, result2 = 0;
pthread_t pth, pth2;
pthread_create(&pth, NULL, threadTest1, &result);
pthread_create(&pth2, NULL, threadTest1, &result2);
//wait for all kids to complete
pthread_join(pth, &status);
pthread_join(pth2, &status2);
if (status != 0) {
printf("result : %d\n",result);
} else {
printf("thread failed\n");
}
if (status2 != 0) {
printf("result2 : %d\n",result2);
} else {
printf("thread2 failed\n");
}
return -1;
}
所以结果是:
*需要四个或五个参数。
before Locking ... in thread
After Create 1 device in thread
before Locking ... in thread
After Create 2 device in thread
deallocated 2 device in thread
deallocated 2 device in thread
thread failed
thread2 failed
*
所以在这里我们可以看到第二个线程在互斥量被释放之前进入临界区。
字符串 "After Create 2 device in thread" 说明了这一点。
如果在释放互斥锁之前到达临界区,则意味着互斥锁工作错误。
如果您有任何想法,请分享。
谢谢
编辑:tkausl 的回答是正确的——但是,即使您切换到使用全局互斥体,由于我的回答中的详细信息,输出也可能不会改变,所以我将其保留在这里。换句话说,有两个原因导致输出可能不是您所期望的,您需要同时修复这两个原因。
特别注意这两行:
mtx.unlock();
cout << "\t deallocated " << counter << " device in thread" << endl;
您的印象似乎是这两行会 运行 一行接一行,但不能保证这会在抢占式多线程环境中发生。相反,可能会发生的是,在 mtx.unlock()
之后可能会切换到另一个线程。
换句话说,第二个线程正在等待互斥体解锁,但第一个线程没有打印"deallocated"消息在第二个线程抢占它之前.
获得预期输出的最简单方法是交换这两行的顺序。
互斥量本身(可能)工作正常(尽管我建议您使用 std::lock_guard
),但是两个线程都创建了自己的 Derived
对象,因此,它们不使用相同的互斥量。
您应将互斥量声明为全局变量并在调用 pthread_create
之前启动它。您使用 pthread_create
创建了两个线程,并且它们都创建了自己的互斥锁,因此它们之间绝对没有同步。
我在继承 类 中使用了互斥锁,但它似乎无法像我预期的那样在线程中工作。请看下面的代码:
#include <iostream>
#include <cstdlib>
#include <pthread.h>
// mutex::lock/unlock
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::thread
#include <mutex> // std::mutex
typedef unsigned int UINT32t;
typedef int INT32t;
using namespace std;
class Abstract {
protected:
std::mutex mtx;
};
class Derived: public Abstract
{
public:
void* write( void* result)
{
UINT32t error[1];
UINT32t data = 34;
INT32t length = 0;
static INT32t counter = 0;
cout << "\t before Locking ..." << " in thread" << endl;
mtx.lock();
//critical section
cout << "\t After Create " << ++ counter << " device in thread" << endl;
std::this_thread::sleep_for(1s);
mtx.unlock();
cout << "\t deallocated " << counter << " device in thread" << endl;
pthread_exit(result);
}
};
void* threadTest1( void* result)
{
Derived dev;
dev.write(nullptr);
}
int main()
{
unsigned char byData[1024] = {0};
ssize_t len;
void *status = 0, *status2 = 0;
int result = 0, result2 = 0;
pthread_t pth, pth2;
pthread_create(&pth, NULL, threadTest1, &result);
pthread_create(&pth2, NULL, threadTest1, &result2);
//wait for all kids to complete
pthread_join(pth, &status);
pthread_join(pth2, &status2);
if (status != 0) {
printf("result : %d\n",result);
} else {
printf("thread failed\n");
}
if (status2 != 0) {
printf("result2 : %d\n",result2);
} else {
printf("thread2 failed\n");
}
return -1;
}
所以结果是:
*需要四个或五个参数。
before Locking ... in thread
After Create 1 device in thread
before Locking ... in thread
After Create 2 device in thread
deallocated 2 device in thread
deallocated 2 device in thread
thread failed
thread2 failed
*
所以在这里我们可以看到第二个线程在互斥量被释放之前进入临界区。 字符串 "After Create 2 device in thread" 说明了这一点。 如果在释放互斥锁之前到达临界区,则意味着互斥锁工作错误。
如果您有任何想法,请分享。
谢谢
编辑:tkausl 的回答是正确的——但是,即使您切换到使用全局互斥体,由于我的回答中的详细信息,输出也可能不会改变,所以我将其保留在这里。换句话说,有两个原因导致输出可能不是您所期望的,您需要同时修复这两个原因。
特别注意这两行:
mtx.unlock();
cout << "\t deallocated " << counter << " device in thread" << endl;
您的印象似乎是这两行会 运行 一行接一行,但不能保证这会在抢占式多线程环境中发生。相反,可能会发生的是,在 mtx.unlock()
之后可能会切换到另一个线程。
换句话说,第二个线程正在等待互斥体解锁,但第一个线程没有打印"deallocated"消息在第二个线程抢占它之前.
获得预期输出的最简单方法是交换这两行的顺序。
互斥量本身(可能)工作正常(尽管我建议您使用 std::lock_guard
),但是两个线程都创建了自己的 Derived
对象,因此,它们不使用相同的互斥量。
您应将互斥量声明为全局变量并在调用 pthread_create
之前启动它。您使用 pthread_create
创建了两个线程,并且它们都创建了自己的互斥锁,因此它们之间绝对没有同步。