免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 14432 | 回复: 6
打印 上一主题 下一主题

多线程环境中的static变量问题【已解决】 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-20 12:51 |只看该作者 |倒序浏览
本帖最后由 crazyhadoop 于 2011-09-20 18:13 编辑

以前被问过一个多线程环境中的static变量问题,到现在一直没搞明白,
今天写了一小段代码,但解释不清,大家帮忙看看吧
multiThread_staticVar.c
  1. #include <stdio.h>                                                               
  2. #include <pthread.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/syscall.h>

  6. #define INIT 1
  7. #define MAX 10

  8. //static int v = INIT;

  9. void *f (void *arg)
  10. {
  11.   static int v = INIT;
  12.   printf("Thread ID = %ld, arg = %d, v = %d\n", syscall(SYS_gettid), *(int *)arg, v);

  13.   while (v < MAX) {
  14.     v += *(int *)arg;
  15. //    printf("v = %d\n", v);
  16.     printf("Thread ID = %ld, arg = %d, v = %d\n", syscall(SYS_gettid), *(int *)arg, v);
  17.     sleep(1);
  18.   }

  19.   return NULL;
  20. }

  21. int main (int argc, char const *argv[])
  22. {
  23.   pthread_t t1, t2;
  24.   int a = 2, b = 1;
  25.   pthread_create(&t1, NULL, f, &a);
  26.   pthread_create(&t2, NULL, f, &b);

  27.   pthread_join(t1, NULL);
  28.   pthread_join(t2, NULL);

  29.   return 0;
  30. }
复制代码
程序运行的结果如下
  1. ~$ ./multiThread_staticVar
  2. Thread ID = 3467, arg = 2, v = 1
  3. Thread ID = 3467, arg = 2, v = 3
  4. Thread ID = 3468, arg = 1, v = 1
  5. Thread ID = 3468, arg = 1, v = 4
  6. Thread ID = 3467, arg = 2, v = 6
  7. Thread ID = 3468, arg = 1, v = 7
  8. Thread ID = 3467, arg = 2, v = 9
  9. Thread ID = 3468, arg = 1, v = 10
复制代码
可以看到,线程3467中static变量v被初始化为1,然后加上了2,变为3,然后sleep,线程3468开始执行,这时打印的v的值还是1,但执行
  1. v += *(int *)arg;
复制代码
即v += 1;后v的值变为4,则v的值变化之前是3,即线程3467 sleep时的值,这里我不理解:当线程3468开始执行f()的时候,v的值应该已经是3,但打印出来是1,但执行
  1. v += *(int *)arg;
复制代码
却变为4,这明明又是在线程3467的执行结果上加了1,为什么?还有,v是static变量,应该只初始化一次,但线程3468开始执行f()时v的值是1,即为其初始化的值,请各位朋友看看



   多线程并发取数据竞争。

论坛徽章:
0
2 [报告]
发表于 2011-09-20 13:32 |只看该作者
lz刚开始学多线程吧?最基本的同步问题,操作v的时候要加锁的。你的问题就是不加锁的关系。

论坛徽章:
0
3 [报告]
发表于 2011-09-20 13:49 |只看该作者
回复 2# samlumengjun
你没有仔细看我的问题,我这里问的是static变量的初始化,不是加锁不加锁

论坛徽章:
0
4 [报告]
发表于 2011-09-20 13:56 |只看该作者
回复 3# edshea


    你这个就是没加锁的问题,一开始创建的2个线程几乎是同时访问v的,所以都读到了初始值1,之后由于sleep的存在,就正常了,简单点验证一下,你就在第一和第二个线程创建函数中间加个sleep就明白了,或者就干脆在线程函数里读写v的时候加锁。

评分

参与人数 1可用积分 +1 收起 理由
crazyhadoop + 1

查看全部评分

论坛徽章:
0
5 [报告]
发表于 2011-09-20 14:42 |只看该作者
回复 4# samlumengjun

果然是这样,多谢!
我想看看多线程环境中的static变量的初始化,现在看来,多线程环境下static变量仍然只初始化一次,但这个是怎么做到的呢?
static变量被第一个线程初始化以后,第二个线程是如何知道这个static变量已被初始化的呢?

论坛徽章:
0
6 [报告]
发表于 2011-09-20 14:53 |只看该作者
静态变量是在编译初始化的之后仅仅是访问或者修改。

论坛徽章:
0
7 [报告]
发表于 2011-09-20 14:54 |只看该作者
回复 6# samlumengjun
全局变量和静态变量的初始化都是编译期就完成,明白了,多谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP