- 论坛徽章:
- 1
|
本帖最后由 cjdao 于 2013-06-23 07:58 编辑
多线程模式是比较流行的一种并发编程模型,多线程编程的一个特点就是线程间共享内存空间;这可以降低线程间通信的开销,但却引来了另外的一个难缠的问题:竟态条件!(因此,甚至有人对多线程模型提出了质疑,看这里)
在多线程编程模型下,解决竟态条件的传统方法就是加锁保护临界区,但这存在影响系统性能、优先级反转等问题.
因此又有人提出了,多线程模型下无锁编程的一些方式:
1.线程内通信框架: Disruptor, 这是一款开源的并发框架,用于线程间无锁的共享数据,看这里。
2.无锁数据结构
无锁数据结构一般基于一个很重要的操作:CAS--Compare And Swap(看这里)。
用C语言表达的一个CAS实现的操作是这样的:- bool compare_and_swap (int *accum, int *dest, int newval)
- {
- if ( *accum == *dest ) {
- *dest = newval;
- return true;
- } else {
- *accum = *dest;
- return false;
- }
- }
复制代码 CAS的一个重要特性是其必须是原子操作。现在大多数CPU都支持指令级别的CAS操作。GCC编译也提供了这样的接口:bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
有了这个原子的CAS后,我们就能实现自己的无锁数据结构了,下面我们就尝试着来实现一个无锁栈为例:
下面的代码中,我们假设malloc与free是线程安全的(至于malloc与free的可重入性与线程安全问题,可以看这里和这里)- /*定义CAS操作*/
- #define CAS __sync_bool_compare_and_swap
- /*
- * 定义stack的数据结构
- */
- typedef struct stack_node {
- struct node *next;
- void *data;
- }stack_node;
- /*栈顶指针*/
- stack_node *top = NULL;
复制代码- /*压栈操作*/
- void stack_push(void *data)
- {
- stack_node *new = malloc(sizeof(struct node));
- new->data = data;
- do {
- new->next = top;
- }while(CAS(&top, new->next, new)!=true);
- }
复制代码- /*出栈操作*/
- void * stack_pop(void)
- {
- stack_node *tmp;
- void *data;
-
- do {
- tmp = top;
- if (!tmp) return NULL;
- }while(CAS(&top, tmp, tmp->next) != true);
- data = tmp->data;
- free(tmp);
- return data;
- }
复制代码 |
评分
-
查看全部评分
|