首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
您找到你想要的搜索结果了吗?
是的
没有找到

Linux下多线程的实现(基于pthread库)

Linux内核在2.2版本中引入了类似线程的机制。Linux提供的vfork函数可以创建线程,此外Linux还提供了clone来创建一个线程,通过共享原来调用进程的地址空间,clone能像独立线程一样工作。Linux内核的独特,允许共享地址空间,clone创建的进程指向了父进程的数据结构,从而完成了父子进程共享内存和其他资源。clone的参数可以设置父子进程共享哪些资源,不共享哪些资源。实质上Linux内核并没有线程这个概念,或者说Linux不区分进程和线程。Linux喜欢称他们为任务。除了clone进程以外,Linux并不支持多线程,独立数据结构或内核子程序。但是POSIX标准提供了Pthread接口来实现用户级多线程编程。

02

[linux][x86]LOCK指令的影响

前言: 一般多线程并行操作,对个别的变量需要使用原子操作,经常用到__sync_fetch_and_add类似的函数,来避免CPU操作各自的cache没有同步内存而造成的数据数错。 在x86平台上,反汇编__sync_fetch_and_add就可以看到,实际上是lock addq $0x1,(%rax)。 如果多个CPU并行使用__sync_fetch_and_add,会不会造成性能问题呢?LOCK指令的影响范围是多少呢?同一个CORE的两个THREAD,同一个SOCKET的两个CORE,以及两个SOCKET之间呢? 分析: 1,sample code 手写一段代码,两个thread分别可以绑定在两个CPU上,一起跑__sync_fetch_and_add,看看时间上是不是会受到影响。需要注意的是“long padding[100]; // avoid cache false-sharing”这行,加上padding用来避免CPU cache的false-sharing问题。 #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <sys/time.h> #include <pthread.h> void bench_atomic(long *l) { long loop; struct timeval start, end; suseconds_t eplased = 0; gettimeofday(&start, NULL); // benchmark for (loop = 0; loop < 0x20000000; loop++) { __sync_fetch_and_add(l, 1); } gettimeofday(&end, NULL); eplased = (end.tv_sec - start.tv_sec)*1000*1000 + end.tv_usec - start.tv_usec; printf("ATOMICC test %ld msec\n", eplased); } void *routine(void *p) { long *l = (long*)p; cpu_set_t my_set; CPU_ZERO(&my_set); CPU_SET(*l, &my_set); sched_setaffinity(0, sizeof(cpu_set_t), &my_set); *l = 0; bench_atomic(l); } int main(int argc, char **argv) { pthread_t p0, p1; long cpu0 = 4; long padding[100]; // avoid cache false-sharing long cpu1 = 8; if (argc != 3) { printf("%s CPU CPU\n", argv[0]); return 0; } cpu0 = atoi(argv[1]); cpu1 = atoi(argv[2]); padding[0] = cpu0; printf("main thread run on CPU %ld, worker thread run on CPU %ld and CPU %ld\n", padding[0], cpu0, cpu1); bench_atomic(&padding[0]); pthread_create(&p0, NULL, routine, &cpu0); pthread_create(&p1, NULL, routine, &cpu1); pthread_join(p0, NULL); pthread_join(p1, NULL); printf("result %ld and CPU %ld\n", cpu0, cpu1); return 0; } 2, cpu topology 使用lscpu判断cpu的分布

04
领券