gpt4 book ai didi

c++ - 何时使用互斥体

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:28:20 26 4
gpt4 key购买 nike

事情是这样的:有一个 float 组 float bucket[5] 和 2 个线程,比如 thread1 和 thread2。

Thread1 负责装满bucket,为bucket 中的每个元素分配一个随机数。当桶装满时,线程 2 将访问 bucket 并读取其中的元素。

以下是我的工作方式:

float bucket[5];
pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread1, thread2;

void* thread_1_proc(void*); //thread1's startup routine, tank up the bucket
void* thread_2_proc(void*); //thread2's startup routine, read the bucket

int main()
{
pthread_create(&thread1, NULL, thread_1_proc, NULL);
pthread_create(&thread2, NULL, thread_2_proc, NULL);
pthread_join(thread1);
pthread_join(thread2);
}

下面是我对 thread_x_proc 的实现:

void* thread_1_proc(void*)
{
while(1) { //make it work forever
pthread_mutex_lock(&mu); //lock the mutex, right?

cout << "tanking\n";
for(int i=0; i<5; i++)
bucket[i] = rand(); //actually, rand() returns int, doesn't matter

pthread_mutex_unlock(&mu); //bucket tanked, unlock the mutex, right?

//sleep(1); /* this line is commented */
}
}

void* thread_2_proc(void*)
{
while(1) {
pthread_mutex_lock(&mu);

cout << "reading\n";
for(int i=0; i<5; i++)
cout << bucket[i] << " "; //read each element in the bucket

pthread_mutex_unlock(&mu); //reading done, unlock the mutex, right?

//sleep(1); /* this line is commented */
}
}

问题

我的实现是否正确?因为输出与我预期的不一样。

...
reading
5.09434e+08 6.58441e+08 1.2288e+08 8.16198e+07 4.66482e+07 7.08736e+08 1.33455e+09
reading
5.09434e+08 6.58441e+08 1.2288e+08 8.16198e+07 4.66482e+07 7.08736e+08 1.33455e+09
reading
5.09434e+08 6.58441e+08 1.2288e+08 8.16198e+07 4.66482e+07 7.08736e+08 1.33455e+09
reading
tanking
tanking
tanking
tanking
...

但是 如果我在每个 thread_x_proc 函数中取消注释 sleep(1);,输出是正确的,tankingreading 像这样互相跟随:

...
tanking
reading
1.80429e+09 8.46931e+08 1.68169e+09 1.71464e+09 1.95775e+09 4.24238e+08 7.19885e+08
tanking
reading
1.64976e+09 5.96517e+08 1.18964e+09 1.0252e+09 1.35049e+09 7.83369e+08 1.10252e+09
tanking
reading
2.0449e+09 1.96751e+09 1.36518e+09 1.54038e+09 3.04089e+08 1.30346e+09 3.50052e+07
...

为什么?使用 mutex 时应该使用 sleep() 吗?

最佳答案

您的代码技术上是正确的,但它没有多大意义,而且它没有按照您的假设进行。

您的代码所做的是,它以原子方式更新数据的一部分,并以原子方式从该部分读取。但是,您不知道发生这种情况的顺序,也不知道数据在读取之前写入的频率(或者根本不知道!)。

您可能想要的是每次在一个线程中只生成一个数字序列,并在另一个线程中每次只读取一个新序列。为此,您要么必须使用额外的信号量,要么更好地使用单一生产者单一消费者队列。

一般来说,“我什么时候应该使用互斥锁”的答案是“如果你能帮助的话,从不”。线程应该发送消息,而不是共享状态。这使得互斥锁在大多数情况下变得不必要,并提供并行性(这是首先使用线程的主要动机)。

互斥锁使您的线程同步运行,因此您也可以只在单个线程中运行。

关于c++ - 何时使用互斥体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8757732/

26 4 0