用线程模拟火车
Simulating a train with threads
编辑:我想我做错了什么,因为当我编译 运行 我的二进制文件两次时,我得到不同的输出..
我试图通过 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);
}
所以我使用静态整数 "cap" 我在桥上开往 2 的火车,但这并没有真正起作用,我不明白为什么..
我的 4 列火车正在开动,然后 2 列上车,另外 2 列等待,当第 2 列离开桥时,只有另一列继续前进,最后一列等待直到第 3 列离开桥去..
实际上,我希望有 4 列火车去,2 列在桥上,2 列等待,当 2 列第一个离开桥时,另外 2 列在桥上。
很抱歉,它有点长,但我想需要理解。
感谢您的帮助!
static int t
是一个全局变量,由不同的线程在没有适当锁定机制的情况下访问和修改:所有列车都可能假设它们是单独的,并且一次只有一个能够锁定互斥体。
您的代码的问题在于 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)
位中额外锁定和解锁的要点是确保没有多个线程同时尝试 change/check 以获得 t
的值. (多个线程同时访问同一个变量通常会导致非常错误的行为!)
编辑:我想我做错了什么,因为当我编译 运行 我的二进制文件两次时,我得到不同的输出..
我试图通过 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);
}
所以我使用静态整数 "cap" 我在桥上开往 2 的火车,但这并没有真正起作用,我不明白为什么..
我的 4 列火车正在开动,然后 2 列上车,另外 2 列等待,当第 2 列离开桥时,只有另一列继续前进,最后一列等待直到第 3 列离开桥去..
实际上,我希望有 4 列火车去,2 列在桥上,2 列等待,当 2 列第一个离开桥时,另外 2 列在桥上。
很抱歉,它有点长,但我想需要理解。
感谢您的帮助!
static int t
是一个全局变量,由不同的线程在没有适当锁定机制的情况下访问和修改:所有列车都可能假设它们是单独的,并且一次只有一个能够锁定互斥体。
您的代码的问题在于 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)
位中额外锁定和解锁的要点是确保没有多个线程同时尝试 change/check 以获得 t
的值. (多个线程同时访问同一个变量通常会导致非常错误的行为!)