原子操作CAS与锁实现

1.互斥锁 mutex

锁被占用,线程走出去,等会再回来查看,有点像非阻塞
使用场景
1.操作复杂/有系统调用,mutex

2.自旋锁 spinlock

锁被占用,线程一直在加锁的地方等待,相当于阻塞
使用场景
1.临界资源操作简单/没有系统调用,spinlock

3.原子操作

将执行汇编变成不可分割
必须cpu指令集支持,比较简单的操作

4.线程私有空间pthread_key

5.共享内存(都是在文件系统上开辟一个空间)

6.CPU的亲缘性

7.setjmp/longjmp




#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#define __USE_GNU
#include <sched.h>

#include <unistd.h>
#include <pthread.h>
#include <setjmp.h>

#include <sys/syscall.h>

#define THREAD_COUNT		3


pthread_mutex_t mutex;
pthread_spinlock_t spinlock;


int inc(int *value, int add) {

	int old;
	__asm__ volatile (
		"lock; xaddl %2, %1;"
		: "=a" (old)
		: "m" (*value), "a" (add)
		: "cc", "memory"
	);
	return old;

}



void *func(void *arg) {

	int *pcount = (int *)arg;

	int i = 0;

	//
	
	while (i ++ < 100000) {
#if 0
		(*pcount) ++;
#elif 0
// 
		pthread_mutex_lock(&mutex);
		(*pcount) ++;
		pthread_mutex_unlock(&mutex);

#elif 0

		pthread_spin_lock(&spinlock);
		(*pcount) ++;
		pthread_spin_unlock(&spinlock);

#else

		inc(pcount, 1);

#endif
		usleep(1);

	}
	

}


pthread_key_t key;

typedef void *(*thread_cb)(void *);


void print_thread1_key(void) {

	int *p = (int *)pthread_getspecific(key);

	printf("thread 1 : %d\n", *p);

}

void *thread1_proc(void *arg) {

	int i = 5;	
	pthread_setspecific(key, &i);

	print_thread1_key();

}

void print_thread2_key(void) {

	char *ptr = (char *)pthread_getspecific(key);

	printf("thread 2 : %s\n", ptr);

}



void *thread2_proc(void *arg) {

	char *ptr = "thread2_proc";
	pthread_setspecific(key, ptr);
	print_thread2_key();
	
}


struct pair {
	int x;
	int y;
};

void print_thread3_key(void) {

	struct pair *p = (struct pair *)pthread_getspecific(key);

	printf("thread 3  x: %d, y: %d\n", p->x, p->y);

}


void *thread3_proc(void *arg) {

	struct pair p = {1, 2};

	pthread_setspecific(key, &p);
	print_thread3_key();

}


// setjmp / longjmp

struct ExceptionFrame {

	jmp_buf env;
	int count;

	struct ExceptionFrame *next;

};

// stack --> current node save





jmp_buf env;
int count = 0;


#define Try 	count = setjmp(env); if (count == 0) 

#define Catch(type)  else if (count == type) 

#define Throw(type)	  longjmp(env, type);

#define Finally			

void sub_func(int idx) {

	printf("sub_func : %d\n", idx);
	//longjmp(env, idx);

	Throw(idx);

}


void process_affinity(int num) {

	//gettid();
	pid_t selfid = syscall(__NR_gettid);

	cpu_set_t mask;
	CPU_ZERO(&mask);

	CPU_SET(1, &mask);

	//selfid
	sched_setaffinity(0, sizeof(mask), &mask);

	while(1) ;
}


int main() {

	// 8
	int num = sysconf(_SC_NPROCESSORS_CONF);

	int i = 0;
	pid_t pid = 0;
	for (i = 0;i < num/2;i ++) {
		pid = fork();
		if (pid <= (pid_t)0) {
			break;
		}
	}

	if (pid == 0) {
		process_affinity(num);
	}

	while (1) usleep(1);


#if 0
	count = setjmp(env);
	if (count == 0) {
		
		sub_func(++count);
	} else if (count == 1) {
		sub_func(++count);
	} else if (count == 2) {
		sub_func(++count);
	} else if (count == 3) {
		sub_func(++count);
	} 
	{
		
		printf("other item\n");
	}
#elif 0

	Try {

		sub_func(++count);
		
	} Catch (1) {

		sub_func(++count);

	} Catch (2) {

		sub_func(++count);

	} Catch (3) {

		sub_func(++count);

	} Finally {

		printf("other item\n");

	}

#endif
	

	pthread_t thid[THREAD_COUNT] = {0};
	int count = 0;

	pthread_mutex_init(&mutex, NULL);
	pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED);

	pthread_key_create(&key, NULL);

#if 0
	int i = 0;
	for (i = 0;i < THREAD_COUNT;i ++) {
		pthread_create(&thid[i], NULL, func, &count);
	}
	

	for (i = 0;i < 100;i ++) {
		printf("count --> %d\n", count);
		sleep(1);
	}
#endif
#if 0
	thread_cb callback[THREAD_COUNT] = {
		thread1_proc,
		thread2_proc,
		thread3_proc
	};

	int i = 0;
	for (i = 0;i < THREAD_COUNT;i ++) {
		pthread_create(&thid[i], NULL, callback[i], &count);
	}

	for (i = 0;i < THREAD_COUNT;i ++) {
		pthread_join(thid[i], NULL);
	}
#endif

	 
	

	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老了希望

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值