免费注册 查看新帖 |

Chinaunix

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

[C] 多线程计数器 原子操 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-24 17:51 |只看该作者 |倒序浏览
我现在有一个需求,多线程并发循环执行一个操作,但是要求精确计数操作了多少次
由于i++操作不是原子操作,所以,从kernel中扣了一段代码,试图进行计数

多次试验后发现,该段代码仍然不是原子操作

atomic自增操作定义如下 (该定义不完整,修改后可以工作的代码在二楼)

#ifndef ATOMIC_32
#define ATOMIC_32




typedef struct {
        volatile int counter;
} atomic_t;

static inline void atomic_inc(atomic_t *v)
{
        asm volatile( "incl %0"
                     : "+m" (v->counter));
}
#endif //ATOMIC_32




测试代码如下
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <pthread.h>



#include "atomic.h"

int thread_num=100;

typedef struct _Count
{
        unsigned int m;
        unsigned int n;
} Count;
typedef struct _Thread
{
        pthread_t thread_id;
        Count count;
} Thread;

Thread* thread;


int atomic_start( Count* count);

atomic_t x={0};


int main(int argc, char** argv)
{
    
  thread=(Thread*)malloc(thread_num*sizeof(Thread));
        memset(thread,0,thread_num*sizeof(Thread));

        int i;
        for(i=0;i<thread_num;i++)
        {
                if(pthread_create(&((thread+i)->thread_id),NULL, atomic_start,&((thread+i)->count)))
                {
                        printf("thread create faild: %d",i--);
                }
        }

        int count=0;
        for(i=0;i<10;i++)
        {
                printf("%d\n",x);
                sleep(1);
        }

        return 0;
}



int atomic_start( Count* count)
{
        pthread_t thread_id=pthread_self();
        pthread_detach(thread_id);

        int i;
        for(i=1000;i>0;i--)
        {
                atomic_inc(&x);
        }
}


[ 本帖最后由 net_robber 于 2009-9-24 22:42 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-09-24 18:18 |只看该作者
搞定
自增定义少了一截
新的atomic自增定义如下
#ifndef ATOMIC_32
#define ATOMIC_32


#define CONFIG_SMP
#ifdef CONFIG_SMP
#define LOCK_PREFIX \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".section .smp_locks,\"a\"\n"   \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"  .align 4\n"                  \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"  .long 661f\n" /* address */  \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".previous\n"                   \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"661:\n\tlock; "

#else /* ! CONFIG_SMP */
#define LOCK_PREFIX ""
#endif

typedef struct {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;volatile int counter;
} atomic_t;

static inline void atomic_inc(atomic_t *v)
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;asm volatile( LOCK_PREFIX "incl %0"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: "+m" (v->counter));
}
#endif //ATOMIC_32

论坛徽章:
1
黑曼巴
日期:2020-02-27 22:54:26
3 [报告]
发表于 2009-09-24 18:20 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
4 [报告]
发表于 2009-09-24 18:22 |只看该作者
难道是在smp环境?

论坛徽章:
0
5 [报告]
发表于 2009-09-24 20:39 |只看该作者
原子操作可以去找glib、ACE等现成封装好的库来用,从kernel里面找代码有时候会有风险

论坛徽章:
0
6 [报告]
发表于 2009-09-24 22:30 |只看该作者
我代码一共才几百行,而且是专用的小工具,用glib或者ACE,成本过高

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
7 [报告]
发表于 2012-02-14 15:04 |只看该作者
atomic。。

论坛徽章:
0
8 [报告]
发表于 2012-02-14 17:56 |只看该作者
不需要atomic。每个线程单独计数,print的时候把它们加起来,顶多volatile + memory barrier。理论上效率比atomic高,因为线程无需smp_lock。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP