多线程和互斥

时间:2012-09-20 07:32:25

标签: c++ linux multithreading pthreads

我是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);
    }
}

5 个答案:

答案 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)

我认为您的代码是正确的,但请注意以下两点:

  1. 这不是例外安全。如果从Some uninteresting operations抛出异常,那么您的互斥锁将永远不会被解锁 - >死锁

  2. 您还可以考虑使用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个不同的线程在这些集合上工作 - 为什么你需要互斥?通常,当您处理一些共享数据时使用互斥锁,并且您不希望两个线程同时处理它,因此您使用互斥锁将其锁定,执行某些操作,解锁。

相关问题