用螺纹模拟火车

时间:2015-02-24 08:02:44

标签: c multithreading pthreads

编辑:我认为我犯了错误,因为当我编译并运行我的二进制文件两次时,我会得到不同的输出..

我试图用pthread来理解线程,所以我做了一些代码来模拟火车在桥上的通过(一次只能处理2列火车)

我设法只用一列火车一次过桥,用这样的代码:

#include <pthread.h>
#include <stdio.h>
#include <time.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void    *train()
{
  int   km;
  static int    t = 0;

  km = 1;
  while (km != 10)
    {
      printf("I'm at %02d km\n", km++);
      sleep(1);
      if (km == 2)
        pthread_mutex_lock(&mutex);
      if (km == 4)
        pthread_mutex_unlock(&mutex);
    }
}

int     main()
{
  pthread_t     train1;
  pthread_t     train2;
  pthread_t     train3;

  pthread_create(&train1, NULL, train, NULL);
  pthread_create(&train2, NULL, train, NULL);
  pthread_create(&train3, NULL, train, NULL);

  pthread_join(train1, NULL);
  pthread_join(train2, NULL);
  pthread_join(train3, NULL);
}

这个工作完美(或者我做错了,如果有的话请告诉我)

然后我试着在2列火车可以同时通过桥的情况下。

#include <pthread.h>
#include <stdio.h>
#include <time.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void    *train()
{
  int   km;
  static int    t = 0;

  km = 1;
  while (km != 30)
    {
      printf("I'm at %02d km\n", km++);
      sleep(1);
      if (km == 2 && t <= 2)
        {
          ++t;
          pthread_mutex_lock(&mutex);
        }
      if (km == 4)
        {
          t--;
          pthread_mutex_unlock(&mutex);
        }
    }
}

int     main()
{
  pthread_t     train1;
  pthread_t     train2;
  pthread_t     train3;
  pthread_t     train4;

  pthread_create(&train1, NULL, train, NULL);
  pthread_create(&train2, NULL, train, NULL);
  pthread_create(&train3, NULL, train, NULL);
  pthread_create(&train4, NULL, train, NULL);

  pthread_join(train1, NULL);
  pthread_join(train2, NULL);
  pthread_join(train3, NULL);
  pthread_join(train4, NULL);
}

所以我使用了一个静态int来&#34; cap&#34;我在火车上的2号火车,但那不是真的有用,我不明白为什么......

我的4列火车正在站着,然后2列车上火车,另外2列等候,当第2个第一个离开桥时,只有一个继续前行,最后一个等待直到第3个离开桥去... ..

实际上,我想要乘坐4列火车,2架桥,2架等待,当2架第一架离开桥架时,另外2架就在桥上。

对不起,这有点长,但需要理解我猜。

感谢您的帮助!

2 个答案:

答案 0 :(得分:6)

您的代码存在的问题是所有pthread_mutex_lock(&mutex);都会等到mutex不再被锁定,然后将其锁定。它实际上并没有检查t的值是什么。

您真正需要的是条件变量

#include <pthread.h>
#include <stdio.h>
#include <time.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void    *train()
{
    int   km;
    static int t = 0;

    km = 1;
    while (km != 30)
    {
        printf("I'm at %02d km\n", km);

        // If we've reached the bridge, wait until less than two trains are on it.
        if (km == 2)
        {
            pthread_mutex_lock(&mutex);
            while (t == 2) { // To be read as: "While two trains are on the bridge, wait."
                pthread_cond_wait(&cond, &mutex);
            }
            ++t; // Put this train onto the bridge.
            pthread_mutex_unlock(&mutex);
        }

        // Leave the bridge.
        if (km == 4)
        {
            pthread_mutex_lock(&mutex);
            --t; // Take this train off the bridge.
            pthread_cond_signal(&cond); // Signal another train to enter.
            pthread_mutex_unlock(&mutex);
        }

        // Move forward 1 km.
        sleep(1);
        ++km;
    }
}

int     main()
{
    pthread_t     train1;
    pthread_t     train2;
    pthread_t     train3;
    pthread_t     train4;

    pthread_create(&train1, NULL, train, NULL);
    pthread_create(&train2, NULL, train, NULL);
    pthread_create(&train3, NULL, train, NULL);
    pthread_create(&train4, NULL, train, NULL);

    pthread_join(train1, NULL);
    pthread_join(train2, NULL);
    pthread_join(train3, NULL);
    pthread_join(train4, NULL);
}

if (km == 4)位中额外锁定和解锁的目的是确保多个线程不会立即尝试更改/检查t的值。 (多个线程一次访问同一个变量通常会导致非常错误的行为!)

答案 1 :(得分:0)

static int t是一个全局变量,由不同的线程访问和修改,没有适当的锁定机制:所有列车都可能认为它们是单独的,只有一个列表能够一次锁定互斥锁。