【问题标题】:pthread not waiting for mutex lock threadFinishedpthread 不等待互斥锁 threadFinished
【发布时间】:2016-04-18 11:47:38
【问题描述】:

你好,下面是我的编码sn-p

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define TIMEOUT 3
int threadFinished = 0;
pthread_mutex_t g_mutex;

void *threadFunction(void* attr)
{
    pthread_mutex_lock(&g_mutex);
    char *pData = (char*)attr;
    if(pData)
    {
        printf("data from main thread is : %s\n",pData);
    }
    sleep(10);
    threadFinished = 1;
    pthread_mutex_unlock(&g_mutex);
    return (void*)"This is thread message !";
}

int main()
{
    pthread_t tid;
    char *retVal = NULL;
    int iTimeOut = TIMEOUT;
    int i =0;
    pthread_mutex_init(&g_mutex,NULL);
    pthread_create(&tid,NULL,threadFunction,"Message from main thread");

    //printf("itimeout %d , threadrunning %d\n",iTimeOut,threadRunning);
    while(iTimeOut!=0 && !threadFinished)
    {
        printf("waiting %d\n",++i);
        sleep(1);
        iTimeOut--;
        printf("changing the threadfinish varible\n");
        //pthread_mutex_lock(&g_mutex); //statement 1
        threadFinished = 1;
        //pthread_mutex_unlock(&g_mutex); // statement 2
        printf("changed the threadfinish varible\n");
    }

    if(iTimeOut==0)
    {
        if(!threadFinished)
        {
            printf("Timed out so cancelling the thread \n");
            pthread_cancel(tid);
        }
        else
        {
            printf("thread finished \n");
        }
    }
    else
    {
        printf("thread finished its job \n");
        pthread_join(tid,(void*)&retVal);

    }
    pthread_mutex_destroy(&g_mutex);
    threadFinished = 0;
    printf("message from thread is :  %s\n",retVal);
    return 0;
}

当 statement1 和 statement2 被注释时,我希望子线程在主线程之前首先更改我的 testrunning 变量,但它只有在 statement1 和 statement2 未注释时才能正常工作。
我的问题是为什么在子线程中互斥锁没有锁定我的 testrunning 变量。它允许主线程修改testrunning 变量。

【问题讨论】:

  • 锁只锁住自己。您不能锁定变量。这甚至意味着什么?
  • @大卫。我的天啊 !简单直接的回答谢谢。我现在明白了,非常感谢

标签: c linux multithreading pthreads


【解决方案1】:

当从多个线程同时访问一个变量时,每个线程需要通过同一个互斥锁来保护对它的访问。 main() 线程没有这样做。

要纠正这个问题,您可以像这样更改 main() 的 while 循环:

  while (iTimeOut != 0)
  {
    {
      pthread_mutex_lock(&g_mutex);
      int finished = threadFinished;
      pthread_mutex_unlock(&g_mutex);

      if (finished)
      {
        break;
      }
    }

    printf("waiting %d\n",++i);

    sleep(1);
    iTimeOut--;

    printf("changing the threadfinish varible\n");

    pthread_mutex_lock(&g_mutex); //statement 1
    threadFinished = 1;
    pthread_mutex_unlock(&g_mutex); // statement 2

    printf("changed the threadfinish varible\n");
  }

您也可能想考虑将锁定范围缩小到线程函数内部的必要位置,如下所示:

void *threadFunction(void* attr)
{
  char *pData = attr; /* No need to cast here in C, as opposed to C++. */
  if(pData)
  {
    printf("data from main thread is : %s\n",pData);
  }
  sleep(10);

  pthread_mutex_lock(&g_mutex);
  threadFinished = 1;
  pthread_mutex_unlock(&g_mutex);

  return "This is thread message !"; /* No need to cast here in C, as opposed to C++. */
}

您应该为所有库调用添加错误检查,以防故障影响剩余的执行。

【讨论】:

  • 谢谢 1. 在 while 循环中检查线程本身会导致任何问题吗? 2. 为什么总是建议使用单个互斥变量在多个线程中锁定和解锁?
  • @BhavithCAcharya:三思而后行:如果您将threadFinished 的测试放在while 条件中,那么您需要将锁定/解锁调用放在哪里?那么这有意义吗?
  • @BhavithCAcharya:关于锁定的概念(需求),您可能想在这里阅读:en.wikipedia.org/wiki/Lock_%28computer_science%29
猜你喜欢
  • 2010-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 2013-06-06
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
相关资源
最近更新 更多