pthread不等待互斥锁lockFinished

时间:2016-04-18 11:47:38

标签: c linux multithreading pthreads

下面是我的编码片段

#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;
}

当声明1&amp; statement2被评论我期望子线程在主线程之前首先更改我的testrunning变量,但只有当statement1和statement2被取消注释时它才能正常工作。
我的问题是为什么在子线程互斥锁没有锁定我的testrunning变量。它允许主线程修改testrunning变量。

1 个答案:

答案 0 :(得分: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++. */
}

如果失败会影响剩余的执行,您应该对所有库调用添加错误检查。