我是Linux编程的新手,所以请耐心等待。我有2个线程类型执行不同的操作,所以我希望每个人拥有它自己的互斥锁。这是我正在使用的代码,它好吗?如果不是为什么?
static pthread_mutex_t cs_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t cs_mutex2 = PTHREAD_MUTEX_INITALIZER;
void * Thread1(void * lp)
{
int * sock = (int*)lp;
char buffer[2024];
int bytecount = recv(*sock, buffer, 2048, 0);
while (0 == 0)
{
if ((bytecount ==0) || (bytecount == -1))
{
pthread_mutex_lock(&cs_mutex);
//Some uninteresting operations witch plays with set 1 of global variables;
pthread_mutex_unlock(&cs_mutex);
}
}
}
void * Thread2(void * lp)
{
while (0 == 0)
{
pthread_mutex_lock(&cs_mutex2);
//Some uninteresting operations witch plays with some global variables;
pthread_mutex_unlock(&cs_mutex2);
}
}
答案 0 :(得分:6)
如果你只有一个司机,那么拥有两辆车是没有优势的。您的Thread2
代码只能在按住cs_mutex2
时取得有用的进展。因此,有多个线程运行该代码是没有意义的。一次只有一个线程可以保存互斥锁,而另一个线程不能执行任何有用的工作。
所以你要完成的是,偶尔没有持有互斥锁的线程将尝试运行并且必须等待另一个。有时候,持有互斥锁的线程会试图释放并重新获取它并被另一个抢先占据。
这是对线程的完全无意义的使用。
答案 1 :(得分:4)
通常,互斥锁与线程无关。 它确保关键区域仅由单个线程访问。 因此,如果您有一些共享区域,例如通过多个线程处理相同的阵列,那么您必须确保对该区域的独占访问。 这意味着,每个线程都不需要互斥锁。您需要一个关键区域的互斥锁。
答案 2 :(得分:3)
我在这里看到三个问题。有一个问题是你的无限循环,另一个关于你有多个线程的意图,并且潜在的未来可维护性“陷阱”。
第一
int bytecount = recv(*sock, buffer, 2048, 0);
while (0 == 0)
是吗?你从套接字读取一些东西,并开始无限循环而不关闭套接字?我只能假设你在循环中做了一些更多的阅读,但是在这种情况下你在持有互斥锁的同时等待外部事件。一般来说,这是一种限制并发性的糟糕模式。可能的模式是让一个线程读取数据,然后将读取的数据传递给进行处理的其他线程。
接下来,您有两组不同的资源,每组资源都由自己的互斥锁保护。然后,您打算为每个资源设置一组线程。但是每个线程都有模式
take mutex
lots of processing
release mutex
tiny window (a few machine instructions)
take mutex again
lots of processing
release mutex
next tiny window
两个线程几乎没有机会并行工作。我怀疑你是否需要为每个资源提供多个线程。
最后一个潜在的维护问题。我只是指出这一点以供将来参考,我认为你现在不需要做任何事情。你有两个函数,供两个线程使用,但最后它们只是任何人都可以调用的函数。如果以后的维护导致这些函数(或函数的重构子集),那么你可以得到两个线程
take mutex 1
take mutex 2
和另一个
take mutex 2
take mutex 1
宾果:僵局。
不是一个容易避免的问题,但至少可以通过仔细的命名选择和重构来帮助维护者。
答案 3 :(得分:2)
我认为您的代码是正确的,但请注意以下两点:
这不是例外安全。如果从Some uninteresting operations
抛出异常,那么您的互斥锁将永远不会被解锁 - >死锁
您还可以考虑使用std :: mutex或boost :: mutex而不是原始互斥锁。对于互斥锁定,最好使用boost :: mutex :: scoped_lock(或std :: analog with modern compiler)
void test()
{
// not synch code here
{
boost::mutex::scoped_lock lock(mutex_);
// synchronized code here
}
}
答案 4 :(得分:2)
如果你有2个不同的数据集和2个不同的线程在这些集合上工作 - 为什么你需要互斥?通常,当您处理一些共享数据时使用互斥锁,并且您不希望两个线程同时处理它,因此您使用互斥锁将其锁定,执行某些操作,解锁。