gpt4 book ai didi

与线程同步混淆 [pthreads]

转载 作者:太空宇宙 更新时间:2023-11-04 02:30:24 25 4
gpt4 key购买 nike

我已经有很长时间的线程问题了。这段代码应该让工作线程在主线程打印出来时增加共享整数的值。但是,我没有得到预期的输出。

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

pthread_mutex_t lock;
int shared_data = 0; //shared data


// Often shared data is more complex than just an int.
void* thread_function(void* arg)
{
int i;
for (i = 0; i < 10; ++i)
{
// Access the shared data here.
pthread_mutex_lock(&lock);
shared_data++;
pthread_mutex_unlock(&lock);
}

return NULL;
}

int main(void)
{
pthread_t thread;
int i;
void* exit_status;
// Initialize the mutex before trying to use it.
pthread_mutex_init(&lock, NULL);
pthread_create(&thread, NULL, thread_function, NULL);
// Try to use the shared data.
for (i = 0; i < 10; ++i)
{
sleep(1);
pthread_mutex_lock(&lock);
printf ("\r for i= %d Shared integer 's value = %d\n", i, shared_data);
pthread_mutex_unlock(&lock);
}
printf("\n");
pthread_join(thread, &exit_status);
// Clean up the mutex when we are finished with it.
pthread_mutex_destroy(&lock);

return 0;
}

这是我期望的:

for i=0 Shared Integer 's value = 0
for i=1 Shared Integer 's value = 1
for i=3 Shared Integer 's value = 2
...
for i=10 Shared Integer 's value =10

但结果是:

for i=0 Shared Integer 's value = 0
for i=1 Shared Integer 's value = 10
for i=3 Shared Integer 's value = 10
...
for i=10 Shared Integer 's value =10

那么我该如何解决呢?

最佳答案

主线程和你的工作线程同时运行。也就是说,如果没有额外的同步,让那些 for 循环彼此完美重合几乎是不可能的。

您的输出正是您所期望的。生成线程所花费的时间允许主线程在其他线程更改共享数据之前进行打印。然后,打印花费的时间太长,以至于另一个线程完全完成其循环并在主线程可以进行第二次迭代之前将共享数据递增到 10。

在一个完美的世界中,这个使用条件变量的小 hack 会得到你想要的:编辑:条件变量对此不是一个好主意。这是使用伪原子变量并且包含 UB :) 的工作版本:

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

pthread_mutex_t want_incr_mut;
pthread_mutex_t done_incr_mut;
int want_incr = 0;
int done_incr = 0;
int shared_data = 0; //shared data

// Not using atomics, so...

void wait_for_want_increment()
{
while (1)
{
pthread_mutex_lock(&want_incr_mut);
if (want_incr)
{
pthread_mutex_unlock(&want_incr_mut);
return;
}
pthread_mutex_unlock(&want_incr_mut);
}
}

void wait_for_done_incrementing()
{
while (1)
{
pthread_mutex_lock(&done_incr_mut);
if (done_incr)
{
pthread_mutex_unlock(&done_incr_mut);
return;
}
pthread_mutex_unlock(&done_incr_mut);
}
}


void done_incrementing()
{
pthread_mutex_lock(&done_incr_mut);

done_incr = 1;
pthread_mutex_lock(&want_incr_mut);
want_incr = 0;
pthread_mutex_unlock(&want_incr_mut);

pthread_mutex_unlock(&done_incr_mut);
}

void want_increment()
{
pthread_mutex_lock(&want_incr_mut);

want_incr = 1;
pthread_mutex_lock(&done_incr_mut);
done_incr = 0;
pthread_mutex_unlock(&done_incr_mut);

pthread_mutex_unlock(&want_incr_mut);
}

// Often shared data is more complex than just an int.
void* thread_function(void* arg)
{
int i;
for (i = 0; i < 10; ++i)
{
wait_for_want_increment();
// Access the shared data here.
shared_data++;
done_incrementing();
}

return NULL;
}

int main(void)
{
pthread_t thread;
int i;
void* exit_status;

// Initialize the mutex before trying to use it.
pthread_mutex_init(&want_incr_mut, NULL);
pthread_mutex_init(&done_incr_mut, NULL);
pthread_create(&thread, NULL, thread_function, NULL);

// Try to use the shared data.
for (i = 0; i <= 10; ++i)
{
printf("\r for i= %d Shared integer 's value = %d\n", i, shared_data);
if (i == 10) break;

want_increment();
wait_for_done_incrementing();
}
printf("\n");
pthread_join(thread, &exit_status);
// Clean up the mutexes when we are finished with them.
pthread_mutex_destroy(&want_incr_mut);
pthread_mutex_destroy(&done_incr_mut);

return 0;
}

在这里,我们只是告诉工作人员我们想要一个增量,并在我们继续之前等待他说他完成了。同时, worker 等待我们想要增量并告诉我们他什么时候完成。

我还将主循环更改为十,因为我认为这是您想要的。

这是我的输出:

for i= 0 Shared integer 's value = 0
for i= 1 Shared integer 's value = 1
for i= 2 Shared integer 's value = 2
for i= 3 Shared integer 's value = 3
for i= 4 Shared integer 's value = 4
for i= 5 Shared integer 's value = 5
for i= 6 Shared integer 's value = 6
for i= 7 Shared integer 's value = 7
for i= 8 Shared integer 's value = 8
for i= 9 Shared integer 's value = 9
for i= 10 Shared integer 's value = 10

关于与线程同步混淆 [pthreads],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44170564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com