头文件
总之缺什么就包含一下吧
#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