免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: snakedy
打印 上一主题 下一主题

[C] 一个看似简单,但包含技术难点的线程问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2012-10-18 12:48 |只看该作者
我觉着你算法输出那里可能有问题,本来类似用法,一般简化成
volatile int k = 0;

void *thr_fn(void *arg)
{
int tmp = __sync_add_and_fetch(&k);
......
}

无需mutex

论坛徽章:
0
12 [报告]
发表于 2012-10-18 12:58 |只看该作者
但是由于k变量在不同线程中空间唯一,且线程执行顺序的随机性,所以可能出现两个线程都执行这个变量计算,造成tmp值的相同;所以想通过锁封闭这种处理,保持tmp数据作为数组下标输出的唯一性,即0到9999值;而不会出现重复值。

论坛徽章:
0
13 [报告]
发表于 2012-10-18 13:04 |只看该作者
__sync_add_and_fetch
是原子操作,相当于带锁的 ++k;

__sync_fetch_and_add
相当于 k++;

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
14 [报告]
发表于 2012-10-18 13:09 |只看该作者
先把问题修正完,后面是代码,楼主测测看。

1.  kk = z * z /kk + kk;
    kk开始为0, 会马上产生除0错。

2. 楼主未见kk除0错,实际上被优化掉了, for(int z = 0; z < count; z++) 没有意义

3. mutex未初始化

4. if(err=0)

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <strings.h>
  4. #include <stdlib.h>
  5. #include <pthread.h>

  6. int count = 1000000;
  7. volatile int k = 0;
  8. pthread_mutex_t mutex;

  9. void *thr_fn(void *arg)
  10. {
  11.         volatile int tmp;
  12. pthread_detach(pthread_self());

  13. pthread_mutex_lock(&mutex);
  14.    k++;
  15.    tmp = k;
  16. pthread_mutex_unlock(&mutex);

  17.    int kk = 0;
  18.    for(int z = 0; z < count; z++)
  19.    {
  20.       kk = z * z /(kk == 0 ? 1 : kk) + kk;        //避免除0错
  21.    }
  22.    printf("kk = %d,  ", kk);        //加上这句,防止kk被当作无用物品(优化掉)

  23.    printf("%05d end pid:%u  tid:%u\n", tmp, getpid(), pthread_self());
  24.         printf("xxx\n");
  25.    pthread_exit(0);
  26.         printf("xxx\n");
  27.    return NULL;
  28. }

  29. int main()
  30. {
  31.    int err;
  32.    int i = 0;
  33.    pthread_t tid = 0;
  34.    pthread_mutex_init(&mutex, NULL);        //加上初始化
  35.    for(; i < 10000; i++)
  36.    {
  37.     printf("i = [%d]\n", i);
  38.    err = pthread_create(&tid,NULL,thr_fn, NULL);
  39.    if(err!=0)        // ==不能写错
  40.       {printf("can't create thread:%s\n",strerror(err));
  41.           return 0;
  42.          }
  43.    }
  44.    sleep(100);
  45.    
  46.    //exit之前,最好加上保证线程已退出的代码
  47.    
  48.    exit(0);
  49. }
复制代码

论坛徽章:
0
15 [报告]
发表于 2012-10-18 13:13 |只看该作者
我主机是AIX的,我到/usr/include下find了一下,没有发现sync_fetch_and_add定义。另外,我的加锁按说也是对的呀,保证了计算的封闭性,为啥还会出现不封闭的现象?

论坛徽章:
0
16 [报告]
发表于 2012-10-18 13:28 |只看该作者
其实我的代码是:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <strings.h>
  4. #include <stdlib.h>
  5. #include <pthread.h>

  6. int count = 1000000;
  7. volatile int k = 0;
  8. pthread_mutex_t mutex;

  9. void *thr_fn(void *arg)
  10. {
  11.         volatile int tmp;
  12. pthread_detach(pthread_self());

  13. pthread_mutex_lock(&mutex);
  14.    k++;
  15.    tmp = k;
  16. pthread_mutex_unlock(&mutex);

  17.    printf("%05d end pid:%u  tid:%u\n", tmp, getpid(), pthread_self());
  18.    pthread_exit(0);
  19.    return NULL;
  20. }

  21. int main()
  22. {
  23.    int err;
  24.    int i = 0;
  25.    pthread_t tid;
  26.    for(; i < 10000; i++)
  27.    {
  28. printf("i = [%d]\n", i);
  29.    err = pthread_create(&tid,NULL,thr_fn, NULL);
  30.    if(err=0)
  31.       printf("can't create thread:%s\n",strerror(err));
  32.    }
  33.    sleep(10);
  34.    exit(0);
  35. }
复制代码
kk那段计算只是我编出来的算法,模拟一段计算,真正需要的是tmp的输出,0-9999保证正确,作为二维指针的数组下标,也是任务的划分,但是目前出现了不同线程中tmp值的重复,也就是说任务分配错误了。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
17 [报告]
发表于 2012-10-18 13:45 |只看该作者
竟然怀疑操作系统, 先把代码写对.

论坛徽章:
0
18 [报告]
发表于 2012-10-18 13:50 |只看该作者
我的代码那里有错了,楼上能给点意见么。我正是不知道那里可以搞定这个竟争问题呢。

论坛徽章:
0
19 [报告]
发表于 2012-10-18 14:17 |只看该作者
可以了,总结一下,楼上两位说的对,pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;没有初值造成的。

论坛徽章:
2
处女座
日期:2014-02-11 17:53:48未羊
日期:2014-12-31 15:13:36
20 [报告]
发表于 2012-10-18 14:17 |只看该作者
错误前面的人都指出来了

kk = z * z /kk + kk;
这一行本来是错的,但是编译器帮你优化掉了

if (err = 0)
应该是
if (err != 0)

mutex要初始化

你的代码在我的机器上没问题
在你的系统上不行,我怀疑是因为mutex没初始化,
初始化并不一定意味着内存置0,可能在有些系统可以,有些不行,这取决于库的实现
你先把初始化加上再试试
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP