社区
Linux/Unix社区
帖子详情
原子操作的问题
970361
2003-08-27 03:42:40
我想在用户空间执行原子操作,请问给如何实现啊?
...全文
216
11
打赏
收藏
原子操作的问题
我想在用户空间执行原子操作,请问给如何实现啊?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
11 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
970361
2003-09-02
打赏
举报
回复
to : CoolQ() ( )
"上边你列出的就是SysV IPC的信号量,也算是原子操作吧。"
〉〉〉〉〉〉〉〉〉〉〉〉〉〉〉〉
while(((semop_ret=semop(semid,&semwait,1))==-1)&&(errno==EINTR));
while(*c!='\0')fputc(*c++,stderr); /* 这里是原子操作吗???*/
while(((semop_ret=semop(semid,&semsignal,1))==-1)&&(errno==EINTR));
wabc
2003-08-29
打赏
举报
回复
pthread中不是有原子操作的函数吗
CoolQ
2003-08-29
打赏
举报
回复
不知道你是用什么CPU?UNP还是SMP?IA还是别的体系?
上边你列出的就是SysV IPC的信号量,也算是原子操作吧。
你说的原子操作也很含糊,你是想把一个数加到另一个变量上,一次性完成,所以不想用信号量还是别的?我不知道lock指令在80x86上算不算特权指令,如果不是的话,你在用户态SMP也是可以使用的。
以下是内核源代码:
#ifdef CONFIG_SMP
#define LOCK "lock ; "
#else
#define LOCK ""
#endif
typedef struct { volatile int counter; } atomic_t;
#define ATOMIC_INIT(i) { (i) }
#define atomic_read(v) ((v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
static __inline__ void atomic_add(int i, atomic_t *v)
{
__asm__ __volatile__(
LOCK "addl %1,%0"
:"=m" (v->counter)
:"ir" (i), "m" (v->counter));
}
感觉这个函数在80x86 UNP 上和 n += i;没有什么区别,只是用__volatile__来拒绝编译器的优化,但是在SMP上多了一个lock指令。
970361
2003-08-29
打赏
举报
回复
我看到很多地方是这么用的,可是不知道到底是不是原子操作,这个东西又不怎么好测试
不知道哪位高手有没有这样用过??
/*******************************************/
#define PERMS S_IRUSR|S_IWUSR
void init_semaphore_struct(struct sembuf *sem,int semnum,
int semop,int semflg)
{
/* 初始话信号灯结构 */
sem->sem_num=semnum;
sem->sem_op=semop;
sem->sem_flg=semflg;
}
int del_semaphore(int semid)
{
/* 信号灯并不随程序的结束而被删除,如果我们没删除的话(将1改为0)
可以用ipcs命令查看到信号灯,用ipcrm可以删除信号灯的
*/
#if 1
return semctl(semid,0,IPC_RMID);
#endif
}
int main(int argc,char **argv)
{
char buffer[MAX_CANON],*c;
int i,n;
int semid,semop_ret,status;
pid_t childpid;
struct sembuf semwait,semsignal;
if((argc!=2)||((n=atoi(argv[1]))<1))
{
fprintf(stderr,"Usage:%s number\n\a",argv[0]);
exit(1);
}
/* 使用IPC_PRIVATE 表示由系统选择一个关键字来创建 */
/* 创建以后信号灯的初始值为0 */
if((semid=semget(IPC_PRIVATE,1,PERMS))==-1)
{
fprintf(stderr,"[%d]:Acess Semaphore Error:%s\n\a",
getpid(),strerror(errno));
exit(1);
}
/* semwait是要求资源的操作(-1) */
init_semaphore_struct(&semwait,0,-1,0);
/* semsignal是释放资源的操作(+1) */
init_semaphore_struct(&semsignal,0,1,0);
/* 开始的时候有一个系统资源(一个标准错误输出) */
if(semop(semid,&semsignal,1)==-1)
{
fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a",
getpid(),strerror(errno));
if(del_semaphore(semid)==-1)
fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a",
getpid(),strerror(errno));
exit(1);
}
/* 创建一个进程链 */
for(i=0;i if(childpid=fork()) break;
sprintf(buffer,"[i=%d]-->[Process=%d]-->[Parent=%d]-->[Child=%d]\n",
i,getpid(),getppid(),childpid);
c=buffer;
/* 这里要求资源,进入原子操作 */
while(((semop_ret=semop(semid,&semwait,1))==-1)&&(errno==EINTR));
if(semop_ret==-1)
{
fprintf(stderr,"[%d]:Decrement Semaphore Error:%s\n\a",
getpid(),strerror(errno));
}
else
{
while(*c!='\0')fputc(*c++,stderr);
/* 原子操作完成,赶快释放资源 */
while(((semop_ret=semop(semid,&semsignal,1))==-1)&&(errno==EINTR));
if(semop_ret==-1)
fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a",
getpid(),strerror(errno));
}
/* 不能够在其他进程反问信号灯的时候,我们删除了信号灯 */
while((wait(&status)==-1)&&(errno==EINTR));
/* 信号灯只能够被删除一次的 */
if(i==1)
if(del_semaphore(semid)==-1)
fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a",
getpid(),strerror(errno));
exit(0);
}
970361
2003-08-29
打赏
举报
回复
那是在内核中使用的啊
970361
2003-08-29
打赏
举报
回复
我需要的原子操作是对链表的增加和删除,而不是简单的将标志增加或者减少
970361
2003-08-29
打赏
举报
回复
因为我写的程序不是针对特定的硬件平台,可能是P4也可能是xeon或者是别的。也不是运行在内核态的,所以不能使用汇编。
我的程序中有一链表是公共数据,其中可能增加或者是减少链表中的一个接点,这个操作由一个特定的线程来完成,这个操作的频率非常低,其他现成来读这个公共链表,有的操作会非常的慢,因为要读数据库,也要等待网络。所以我只好放在其他线程。但是成个程序的性能要求太高,响应必须非常的及时。我只是想在对链表的删除或者增加接点的时候保证是原子的,避免过多的互斥,因为我理论计算的记过互斥操作会站用20%左右的资源,这样多线程带来的好出就被抵消了,而且增加了复杂程度。
要是在对链表的增加和删除的关键地方能够实现原子操作那么程序就可以简单很多,而且效率上也提高不少。
CoolQ
2003-08-28
打赏
举报
回复
应该是可以,你可以参看内核里的/usr/src/linux-2.4/include/asm-i386/atomic.h
里边有相应的函数,大部分都是一些汇编
970361
2003-08-28
打赏
举报
回复
谁能帮忙吗
970361
2003-08-27
打赏
举报
回复
是的,我考虑过用信号量,但是那样太复杂,如果有个原子操作可以完成的话,那样会非常简单,内核中是可以使用的,但是我不知道,在用户空间如何实现
CoolQ
2003-08-27
打赏
举报
回复
用信号量?
原子操作
与并发、ABA
问题
、CAS
本文探讨了
原子操作
在并发编程中的关键作用,如何通过原子类如Java的AtomicInteger和CAS操作确保数据一致性,以及ABA
问题
的定义、示例和解决策略,包括版本号标记、循环CAS和基于栈的解决方案。,
Java的
原子操作
及存在的三个
问题
本文深入探讨了
原子操作
的重要性及其实现方式,特别是在多处理器环境下防止数据竞争的关键作用。通过对比常规自加操作与原子自加操作,展示了
原子操作
如何避免数据丢失。同时,文章详细解释了比较并交换(CAS)操作的工作原理,包括其解决原子性
问题
的机制以及存在的ABA
问题
、循环时间开销和多变量
原子操作
限制。此外,还介绍了JDK中提供的原子类及其解决方法。
Atomic
原子操作
与ABA
问题
本文详细介绍了Java中基于
原子操作
的并发工具类,如AtomicInteger、AtomicReference等,及其在解决并发
问题
中的应用。讲解了原子更新基本类型、数组、引用以及字段的方法,并探讨了ABA
问题
及其解决方案,如AtomicStampedReference的使用。
CAS实现
原子操作
的三个
问题
本文深入探讨了Java中的CAS机制,解析了其在并发控制中的应用,包括
原子操作
的实现方式及存在的ABA
问题
、自旋时间长开销大和只能保证单个共享变量原子性的局限性。并介绍了如何使用AtomicStampedReference解决ABA
问题
。
原子操作
类的使用以及ABA
问题
的解决
本文详细介绍了Java中的
原子操作
类,包括AtomicInteger、AtomicReference、AtomicIntegerArray等,及其使用方法。同时,针对ABA
问题
,讨论了AtomicStampedReference和AtomicMarkableReference的解决方案,展示了它们如何通过版本号或标记来防止数据变化的不确定性。最后,探讨了Unsafe类在
原子操作
中的作用,以及如何利用它来实现不同基本类型的原子更新。
Linux/Unix社区
23,223
社区成员
74,536
社区内容
发帖
与我相关
我的任务
Linux/Unix社区
Linux/Unix社区 应用程序开发区
复制链接
扫一扫
分享
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章