#include <stdio.h>#include <pthread.h>long count = 0;void *run(void *n) { long i, nums = *((long *)n); for (i = 0; i < nums; i++) { count++; } return NULL;}void main() { pthread_t t1, t2; long nums = 100000; pthread_create(&t1, NULL, run, &nums); pthread_create(&t2, NULL, run, &nums); pthread_join(t1, NULL); pthread_join(t2, NULL); printf("count = %d", count);}
如果我把 nums 设置为 10000,那么每次都准确输出 20000。或者设置的值比 10000 要少时也能准确输出。如果我把 nums 设置为 100000,那么每次输出的值都好像是随机的,范围在 100000 到 200000 之间。
如果是因为线程之间执行顺序的问题导致输出不确定,那为什么当值为 10000 时输出的值是比较确定的?
设置为10000或者更少的时候,执行时间短,另一个线程还没来得及和当前执行的线程竞争资源,当前执行的线程就执行完了。
个人理解
和CPU调度有关两个线程全局共享变量count;
此时尽管两个线程进行了2次加法运行但是结果却增加了一次
这就是值小于等于 20000的原因有一本书写的特别清楚我给你找找:
这本数的第2章介绍并发的时候有详细介绍
另外一本是:
Is Parallel Programming Hard, And, If So, What Can You Do About It? (Release v2023.06.11a)
这种情况下,两个线程有对同一变量的未经同步的写操作,所以存在 data race 。
存在 data race 的情况下,语言并不保证程序的结果。
也许你换台机器、换个编译器、换个编译选项、等等,就又能看到不同的现象。
对于貌似“确定”的结果,可能是由于在一个线程启动后,另一个线程还没有开始运行的很短的时间的,第一个线程的 10000 个循环已经做完了。所以两个线程对同一变量的操作实际并没有“重叠”。
当然也还可能有其它原因。
这段代码是一个简单的多线程程序,用于展示线程并发和增加全局变量的复杂行为。首先,我们先对代码进行简单解释。
#include <stdio.h>
和 #include <pthread.h>
是标准库的头文件,分别用于标准输入输出和 POSIX 线程操作。
long count = 0;
定义了一个全局的 long 类型变量 count
并初始化为 0。
void *run(void *n)
是一个线程函数,它接受一个 void 指针 n
,然后将其转换为 long 指针,解引用得到 nums
的值,然后在循环中将 count
增加 nums
次。
void main()
是程序的主函数,其中:
pthread_t t1, t2;
定义了两个线程的句柄。long nums = 100000;
定义并初始化了一个 long 类型的变量 nums
,值为 100000。pthread_create(&t1, NULL, run, &nums);
和 pthread_create(&t2, NULL, run, &nums);
创建了两个线程,并启动它们运行 run
函数。pthread_join(t1, NULL);
和 pthread_join(t2, NULL);
是阻塞调用,等待线程 t1 和 t2 完成。count
的值。现在,让我们来看看程序的输出问题。当 nums
为 10000 时,每次都能准确输出 20000,这是因为两个线程每次都会将 count
增加 10000 次,所以总和是 20000。当 nums
的值比 10000 小时,结果也是准确的,因为两个线程增加的次数是固定的。
然而,当 nums
为 100000 时,输出是随机的。这是因为线程的调度是不确定的,可能存在一个线程先于另一个线程开始或结束的情况。这导致两个线程可能不会同时完成,因此输出的 count
值会在 100000 到 200000 之间波动。
此外,由于 count
是全局变量,没有进行同步操作(如互斥锁),所以当两个线程同时修改它时,可能会出现数据竞争(data race)。这可能是导致输出不稳定的原因之一。为了解决这个问题,可以使用互斥锁(如 pthread_mutex_t)来保护对 count
的访问。
执行者。newFixedThreadPool(5)在池中创建5个线程,然后在循环中再创建100个线程。这种理解正确吗?然后池中的5个线程将执行100个工作线程队列中的每个线程。 总共创建了105个线程?我原以为只创建了5个线程,但每个也是一个线程。
大概功能就是计算一个数组内的元素的和,怎么约束 T 让这段程序编译通过
我有一个之前写的类,其中,比方说,有一个数据成员int count,一个函数fun. 我希望我做一个功能,在fun函数执行时,qt界面上的label实时地显示count的值. 但我不想修改已经写好的类,比方说在fun函数里加上修改label的值的内容.能吗?这样的话应该怎么办好?
C++的这些宏怎么理解 下面代码出自:https://github.com/sharkdp/dbg-macro的dbg.h头文件中 我尝试用渐进的方式去理解,尝试如下代码去理解前两行宏 发现代码不可编译,故尝试问之
这是怎么回事?我不明白count()是如何既等于withCallback又有一个主体的;不知何故,它是在withCallback返回的dataframe上调用的,但我不明白语法。