c/c++linux后台开发3.2.1锁、原子操作CAS、try/catch、线程私有空间

头文件

总之缺什么就包含一下吧

#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>

//适用于临界区中有系统调用的情景
pthread_mutex_t mutex;
//适用于临界区中没有系统调用,比较简单的情景(如链表等操作数据结构)
pthread_spinlock_t spinlock;

CAS


int inc(int *value, int add) {

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

}

//if (*addr==_old)*addr=_new; return previous value of *addr;
unsigned long cmpxchg(void *addr, unsigned long _old, unsigned long _new) {

	unsigned long prev;
	volatile unsigned int *ptr = (volatile unsigned int *)addr;
	__asm__ volatile (
		"lock; cmpxchg %1, %2;"
		: "=a" (prev)
		: "r" (_new), "m" (*ptr), "0" (_old)
		: "memory"
	);
	return prev;

}

CAS比锁效率更高
锁在所有情况下都可以用,而CAS只有指令集支持的操作才能使用
获取锁必须按顺序,不然会导致死锁

线程私有空间

线程内部的全局变量

pthread_key_t key;
int main() {
    pthread_key_create(&key, NULL);
}
void *thread1_proc(void *arg) {

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

	int *p = (int *)pthread_getspecific(key);
	printf("thread 1 : %d\n", *p);

}

适用于需要私有变量又不能通过传参获得的情况

try/catch实现

#include <setjmp.h>

       int setjmp(jmp_buf env);
       int sigsetjmp(sigjmp_buf env, int savesigs);

       noreturn void longjmp(jmp_buf env, int val);
       noreturn void siglongjmp(sigjmp_buf env, int val);
简单的实现
jmp_buf env;
int err_number = 0;

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

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

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

#define Finally	

这样的实现并不能让try套叠,也没有解决多线程的问题

专业的实现
struct ExceptionFrame {

	jmp_buf env;
	int count;

	struct ExceptionFrame *next;

};

每套叠一次增加一个frame,用头插法,并把链表头存在线程私有空间中,这样又解决了多线程的问题

设置线程cpu亲和性


void process_affinity(int num) {

	//get tid;
	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) ;
}

获取cpu个数

sysconf(_SC_NPROCESSORS_CONF);

参考

零声教育c/c++linux后台开发3.2.1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值