PThread问题

时间:2011-07-01 14:33:26

标签: c++ c multithreading pthreads mutex

我正在尝试制作一个小线程示例。我想要一个变量,每个线程都尝试递增它,然后一旦达到某个点就停止。每当变量被锁定时,我想要打印出某种类型的消息,如“线程x试图锁定,但不能”,以便我知道它正常工作。这是我编写代码的第一天,所以请随时在代码中指出任何不必要的内容 -

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

#define NUM_THREADS 2
pthread_t threads[NUM_THREADS];
pthread_mutex_t mutexsum;

int NUMBER = 0;
void* increaseByHundred(void* threadid) {

    if(pthread_mutex_lock(&mutexsum))
        cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT";

    else {
        for(int i=0;i<100;i++) {
            NUMBER++;
            cout<<"\nNUMBER: "<<NUMBER;
        }
        pthread_mutex_unlock(&mutexsum);
        pthread_exit((void*)0);
    }
}


int main(int argc, char** argv) {

    int rc;
    int rc1;
    void* status;

    pthread_attr_t attr;

    pthread_mutex_init(&mutexsum, NULL);
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    rc = pthread_create(&threads[0], &attr, increaseByHundred, (void*)0);
    rc1 = pthread_create(&threads[1], &attr, increaseByHundred, (void*)1);

    pthread_attr_destroy(&attr);

    while(NUMBER < 400)
        pthread_join(threads[0], &status);


    pthread_mutex_destroy(&mutexsum);
    pthread_exit(NULL);

}

我正在按照此处找到的教程https://computing.llnl.gov/tutorials...reatingThreads 并试图使他们的互斥体例子适应这个想法。代码将其增加到199然后停止。我猜是因为线程只执行一次例程。有没有办法让他们只是做他们的例行,而不是你创建它们,所以我可以说

有些东西 做你的日常工作 ?

我在那里有pthread_join只是因为它与他们的教程相似。我甚至没有那么清楚。我很确定这条线是问题...我只是不知道如何解决它。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:2)

  

每当变量被锁定时,我想要打印出某种类型的消息,例如“线程x试图锁定,但不能”,以便我知道它正常工作。

你为什么这么想?你刚学习线程。首先学习基础知识。不要深入潜入pthread_mutex_trylock或为错误检查配置的互斥锁。在学习如何跑步之前,你需要学会走路。

基础知识涉及使用默认设置进行互斥初始化使用,并使用pthread_mutex_lock来获取锁定。使用默认设置时,如果存在重大问题,pthread_mutex_lock将仅返回非零值。这里只会出现两个问题:死锁和坏的互斥指针。两者都没有恢复;唯一真正的解决方案是修复代码。关于你唯一可以做的就是抛出一个你没有捕获的异常,调用exit()或abort()等。

其他一些线程锁定了互斥锁并不是一个大问题。这根本不是问题。 pthread_mutex_lock将阻止(例如,进入睡眠状态),直到锁定可用。从pthread_mutex_lock返回零意味着调用线程现在具有锁定。只需确保在使用受保护的内存后释放锁定。

修改
这是一个建议,可以让你看到线程机制正如宣传的那样工作。

  1. 在输入increaseByHundred时,会打印一条带时间戳的消息,指示该功能的输入。您可能希望在此使用C printf而不是C ++ I / O. printf()和相关函数是线程安全的。 C ++ 2003 I / O不是。
  2. pthread_mutex_lock成功返回后,打印另一条带有时间戳的消息,表明锁定成功。
  3. sleep()几秒钟,然后在拨打pthread_mutex_unlock()之前打印另一张带有时间戳的消息。
  4. 在致电pthread_exit()之前,请执行相同操作。
  5. 最后一条评论:您正在检查pthread_mutex_lock的错误回复。为了完整性,并且因为每个优秀的程序员都是偏执狂,所以你应该从pthread_mutex_unlock检查返回状态。

    pthread_exit怎么样?它没有返回状态。在调用pthread_exit之后,可以打印一些消息,但如果您使用的是不兼容的线程库版本,则只能访问该语句。函数pthread_exit()无法返回到调用函数。期。担心pthreads_exit()返回时发生的事情是锡箔帽运动。虽然优秀的程序员应该是偏执狂,但他们不应该是偏执型精神分裂症。

答案 1 :(得分:0)

pthread_mutex_trylock():

if (pthread_mutex_trylock(&mutex) == EBUSY) {
    cout << "OMG NO WAY ITS LOCKED" << endl;
}

值得注意的是,如果互斥锁未锁定,它将能够获取锁定,然后它将表现得像常规pthread_mutex_lock()

答案 2 :(得分:0)

pthread_mutex_lock通常只会阻塞直到它获得锁定,这就是为什么行cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT";没有运行的原因。

中也有问题
while(NUMBER < 400)
     pthread_join(threads[0], &status);

因为你只有2个线程而且数字永远不会达到400.你还想在第一次迭代时加入线程[0],然后线程[1] ......