CLHLock的C语言实现
来源:互联网 发布:四知的学法指导 编辑:程序博客网 时间:2024/06/06 02:15
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#define FALSE 0
#define TRUE 1
static int shareddata = 50;
struct qnode* tail;
struct qnode q;
pthread_key_t myPred;
typedef struct qnode
{
int locked;
}QNode;
{
int t_id;
QNode qnode;
QNode* myNode;
QNode* myPred;
typedef struct thread
{
pthread_t t;
Arg arg;
}Thread;
QNode* getAndSet(QNode* qnode)
{
pthread_mutex_lock(&mutex);
QNode* pred = tail;
tail = qnode;
pthread_mutex_unlock(&mutex);
return pred;
}
int isLock()
{
int ret;
QNode* qnode = (QNode*)pthread_getspecific(myPred);
if (qnode == NULL)
return FALSE;
return (qnode->locked)?TRUE:FALSE;
}
void lock()
{
/*得到线程的私有变量。*/
QNode* qnode = (QNode*)pthread_getspecific(myNode);
qnode->locked = TRUE;
QNode* pred = getAndSet(qnode);
pthread_setspecific(myPred, pred);
while(pred->locked)
{
}
}
void unlock()
{
QNode* qnode = (QNode*)pthread_getspecific(myNode);
qnode->locked = FALSE;
QNode* pred = (QNode*)pthread_getspecific(myPred);
pthread_setspecific(myNode, pred);
}
void initCLHlock()
{
q.locked = FALSE;
tail = &q;
}
void initThread(Thread* t, int i)
{
t->arg.qnode.locked = TRUE;
t->arg.myNode = &(t->arg.qnode);
t->arg.myPred = NULL;
t->arg.t_id = i;
}
void* run(Arg* t_arg)
pthread_setspecific(myPred, t_arg->myPred);
while (1)
{
/*lock*/
lock();
if (shareddata > 0)
{
printf("%d get %dth ticket\n", t_arg->t_id, shareddata);
if (isLock())
printf("locked!\n");
shareddata--;
/*unlock*/
unlock();
}
else
{
/*unlock*/
unlock();
break;
}
}
}
void main()
{
clock_t start, end;
Thread t[10];
initCLHlock();
pthread_key_create(&myNode, NULL);
pthread_key_create(&myPred, NULL);
int i;
for (i=0; i<4; i++)
{
initThread(&t[i], i);
}
/*start*/
start = clock();
for (i=0; i<4; i++)
if (ret != 0)
{
printf("creat_thread error!\n");
exit(0);
}
}
/*join*/
for (i=0; i<4; i++)
{
pthread_join(t[i].t, NULL);
}
end = clock();
printf("shareddata:%d\n", shareddata);
printf("speed %f seconds\n", (double)(end-start)/CLOCKS_PER_SEC);
}
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#define FALSE 0
#define TRUE 1
static int shareddata = 50;
struct qnode* tail;
struct qnode q;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
/*相当于Java的ThreadLocal*/
pthread_key_t myPred;
typedef struct qnode
{
int locked;
}QNode;
/*线程的参数*/
{
int t_id;
QNode qnode;
QNode* myNode;
QNode* myPred;
}Arg;
typedef struct thread
{
pthread_t t;
Arg arg;
}Thread;
QNode* getAndSet(QNode* qnode)
{
pthread_mutex_lock(&mutex);
QNode* pred = tail;
tail = qnode;
pthread_mutex_unlock(&mutex);
return pred;
}
int isLock()
{
int ret;
QNode* qnode = (QNode*)pthread_getspecific(myPred);
if (qnode == NULL)
return FALSE;
return (qnode->locked)?TRUE:FALSE;
}
void lock()
{
/*得到线程的私有变量。*/
QNode* qnode = (QNode*)pthread_getspecific(myNode);
qnode->locked = TRUE;
QNode* pred = getAndSet(qnode);
pthread_setspecific(myPred, pred);
while(pred->locked)
{
}
}
void unlock()
{
QNode* qnode = (QNode*)pthread_getspecific(myNode);
qnode->locked = FALSE;
QNode* pred = (QNode*)pthread_getspecific(myPred);
pthread_setspecific(myNode, pred);
}
void initCLHlock()
{
q.locked = FALSE;
tail = &q;
}
void initThread(Thread* t, int i)
{
t->arg.qnode.locked = TRUE;
t->arg.myNode = &(t->arg.qnode);
t->arg.myPred = NULL;
t->arg.t_id = i;
}
void* run(Arg* t_arg)
{
/*设置线程的私有变量。此时已经在某一个线程内部,所以会自动的建立map。*/
pthread_setspecific(myPred, t_arg->myPred);
while (1)
{
/*lock*/
lock();
if (shareddata > 0)
{
printf("%d get %dth ticket\n", t_arg->t_id, shareddata);
if (isLock())
printf("locked!\n");
shareddata--;
/*unlock*/
unlock();
}
else
{
/*unlock*/
unlock();
break;
}
}
}
void main()
{
clock_t start, end;
Thread t[10];
initCLHlock();
pthread_key_create(&myNode, NULL);
pthread_key_create(&myPred, NULL);
int i;
for (i=0; i<4; i++)
{
initThread(&t[i], i);
}
/*start*/
start = clock();
for (i=0; i<4; i++)
{
/*创建并执行线程,参数是最后一个参数*/
if (ret != 0)
{
printf("creat_thread error!\n");
exit(0);
}
}
/*join*/
for (i=0; i<4; i++)
{
pthread_join(t[i].t, NULL);
}
end = clock();
printf("shareddata:%d\n", shareddata);
printf("speed %f seconds\n", (double)(end-start)/CLOCKS_PER_SEC);
}
关于pthread_key_t
这个其实是一个hash。每一个pthread_key_t代表一个全局的线程私有变量。也就是说,变量虽然是全局的,但是线程里面对他的改变只改变在线程内部的那个copy。这样做的原因是:因为线程使用的数据都是以参数的形式传进去,这些参数肯定是在线程外部,但是有时候这些变量的该表不需要通知其他线程,仅仅是线程自己使用。像上面这个例子,每个线程只关心自己的myNode与myPred两个指针的指向,而不关心其他线程这两个指针的指向,所以在这种情况下,将两个变量作为线程私有会加快速度。在pthread_getspecific与pthread_setspecific时,通过hash查找到对应的值。
0 0
- CLHLock的C语言实现
- CLHLock的实际应用
- CLHLock
- C语言实现的井字棋
- C语言--容器的实现。
- C语言--迭代器的实现。
- 栈的C语言实现
- 汉诺塔的C语言实现
- C语言实现的俄罗斯方块
- ls的C语言实现
- 队列的C语言实现
- 单链表的C语言实现
- c语言readline的实现
- C语言状态机的实现
- 组合的C语言实现
- 栈的C语言实现
- CRC16的C语言实现
- C语言中链表的实现
- Rotate Array 数组的旋转
- 安卓实现摁两次返回键退出程序
- STL中的全排列(1)未完待续。
- 一个北邮牛人面试英特尔的经历
- Nginx 跳转fastdfs存储图片地址报错问题分析过程汇总
- CLHLock的C语言实现
- 【HTML】HTML中使用CSS样式的几种方式
- hdu 2041 超级楼梯(简单dp 0/1背包变形)
- 杂谈---技术与管理
- 利用redis实现带优先级的消息队列
- 做人要检点
- Reverse Bits 翻转进制位
- unix环境高级编程源代码在ubuntu下运行
- Number of 1 Bits 数字二进制中1的个数