gpt4 book ai didi

C中的打印函数mutex无法正常工作

转载 作者:行者123 更新时间:2023-11-30 19:00:29 27 4
gpt4 key购买 nike

我试图给线程一个id,然后我想打印我给出的每个线程id,但是我猜有一种关于互斥体的情况,我认为我正在处理关键部分,但似乎我不能.

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

struct info{
int id;
int flag;
};

void *print_info(void* arg){
struct info *arg_struct = (struct info*) arg;

pthread_mutex_lock(&m);

printf("%d ", arg_struct->id);
pthread_mutex_unlock(&m);

pthread_exit(0);

}
int main(int argc, char *argv[])
{
int number = 10;
pthread_t tid[number];
for (int i = 0; i < number; ++i) {
int info[2];
info[0] = i;
info[1] = 0;

pthread_create(&tid[i], NULL, print_info, &info);
}
for (int i = 0; i < number; ++i) {
pthread_join(tid[i], NULL);
}

return 0;
}

这是输出:1 2 3 4 5 6 7 8 9 9

每次执行时都会有所不同,但或多或​​少的概念是相同的,即不打印某些值,而是多次打印一些值。

但是预期的输出是这样的:0 1 2 3 4 5 6 7 8 9

[或者不按顺序排列的东西,但我猜每个值都被精确打印一次]谢谢

最佳答案

为每个线程提供自己的控制数据

正如所写,您的代码无法保证输出数字的顺序 - 线程执行的顺序取决于操作系统和硬件。通过确保每个线程都有自己的struct info 可以使用,您可以轻松地确保每个 ID 仅打印一次。您现有的代码(a)使用结构对数组进行类型双关,这是一个坏主意( alkcomment ),并且(b)重用主程序堆栈上的相同空间,以便到线程在工作时,主循环可能会更改存储的值。

这就是@rafix07comment中说。您声称已尝试修复但没有成功。我必须得出结论,您修改后的代码没有完成必要的操作。

您需要使用更像这样的代码(它还在每次运行结束时打印换行符):

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

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

struct info
{
int id;
int flag;
};

static void *print_info(void *arg)
{
struct info *arg_struct = (struct info *)arg;

pthread_mutex_lock(&m);

printf("%d ", arg_struct->id);
pthread_mutex_unlock(&m);

pthread_exit(0);
}

int main(void)
{
int number = 10;
pthread_t tid[number];
struct info info[number];
for (int i = 0; i < number; ++i)
{
info[i].id = i;
info[i].flag = 0;
pthread_create(&tid[i], NULL, print_info, &info[i]);
}

for (int i = 0; i < number; ++i)
{
pthread_join(tid[i], NULL);
}
putchar('\n');

return 0;
}

当我连续运行 10 次时,我得到了输出:

0 7 2 8 3 1 4 9 5 6 
1 8 0 9 2 3 6 5 4 7
0 4 5 2 3 6 7 1 8 9
0 1 2 3 4 5 6 7 8 9
2 7 0 3 5 6 4 8 1 9
2 0 7 6 3 5 4 8 9 1
0 9 1 3 5 6 7 2 8 4
0 7 1 8 4 3 9 2 5 6
0 7 1 8 3 5 4 2 9 6
0 3 4 5 6 1 2 8 7 9

正如您所看到的,每个数字 0..9 在每行输出中出现一次,但线程执行的顺序却是不确定的。

我不相信互斥体能给你带来任何东西。所有 I/O 函数(例如 printf())的行为必须类似于使用 flockfile()进入时和返回时funlockfile()

在运行 macOS Mojave 10.14.6(不要问!)和 GCC 9.2.0 的 MacBook Pro 上进行测试。

保证顺序

一个简单的修改就可以确保顺序——主线程在启动线程之前锁定互斥锁,线程在退出之前解锁它。然而,这意味着没有有意义的并发——你不妨这样写:

for (int i = 0; i < 10; i++)
printf("%d ", i);
putchar('\n');

这将避免线程后启动、运行和清理的所有开销。

修改后的代码只是将 print_info() 函数中的一行移动到 main() 中:

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

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

struct info
{
int id;
int flag;
};

static void *print_info(void *arg)
{
struct info *arg_struct = (struct info *)arg;

printf("%d ", arg_struct->id);
pthread_mutex_unlock(&m);

pthread_exit(0);
}

int main(void)
{
int number = 10;
pthread_t tid[number];
struct info info[number];
for (int i = 0; i < number; ++i)
{
info[i].id = i;
info[i].flag = 0;
pthread_mutex_lock(&m);
pthread_create(&tid[i], NULL, print_info, &info[i]);
}

for (int i = 0; i < number; ++i)
{
pthread_join(tid[i], NULL);
}
putchar('\n');

return 0;
}

输出:

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9

关于C中的打印函数mutex无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59553289/

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