LINUX学习散记

目录

1、__thread修饰的变量

2、共享内存

3、有名信号量和无名信号量

4、unix相关标准


1、__thread修饰的变量

__thread 标识符修饰的全局或静态变量是线程独立的,线程对该变量的操作对其它线程来说是不可见的。然而线程之间共享内存空间的,因此要达到如些效果就需要针对该变量为每个线程分配变量的存储位置。表现为不同的线程虽然使用的变量名字是一样的,但是变量的值是独立属于各个线程的。

例如:创建了2个线程,定义一个全局变量pthread_t __thread tid,线程1的tid保存的是在线程1调用pthread.self()返回的值,线程2的tid保存的是线程2调用pthread.self()返回的值。

另外一种创建线程特定数据(Tthread-specific data)的方式是通过 pthread_key_create 创建键值映射。每个线程通过键访问线程特定的数据。glibc 中键集中分配管理,值分开存储的方式提供 TSD 数据。

2、共享内存

linux的共享内存有下面两种:

(1)shmget,最常用的一种。

(2)shm_open,类似open函数,不过使用共享内存的方式进行读写文件,这里的文件就是用共享内存保存。

对于第一种,例如场景为两个进程之间进行实时通信且要求时延越低越好,这个时候使用共享内存是比较合适的方法,因为共享内存是进程间通信效率最高的一种方式。

linux的api使用步骤如下:

对于创建共享内存的创建者来说:

(1)生成唯一的key值,可以自己定义key值,建议使用下面的函数ftok自动生成key值。

key = ftok(“/tmp/”, id) // 第一个参数是文件目录,linux会根据第一个参数来产生一个文件索引,就是一个整数,然后再根据第二个参数id最终生成唯一的key值。

(2)计算所需的共享内存大小shm_size并创建共享内存。

shmid = shmget(key, shm_size, 0666 | IPC_CREAT)

创建者就可以按照约定的规则去写和读其中一块共享内存,发送和接收消息。

对于使用者来说:

(1)使用上面的key值打开已经创建好的共享内存。

shmid = shmget(key, 0, 0666|IPC_CREAT) // 第二个参数传入0表示打开已经创建的key的共享内存。

(2)将Shmid对应的共享内存地址映射到当前进程的地址空间。

ADDR g_shm_memory = shmat(shmid, null, 0)

使用者就可以按照约定的规则去写和读其中一块共享内存,接收和发送消息。

对于第二种shm_open,使用场景如代码需要输出log日志且同时比较关心代码性能的时候。

3、有名信号量和无名信号量

有名信号量可以在不同进程间共享,必须指定一个特定的文件名称进行关联,相关函数为sem_open。

使用api步骤:

(1)sem_unlink(name) // 如果name对应的有名信号量exist,就先删除这个信号量。

(2)sem = sem_open(name, O_CREAT | O_EXCL, 0600, 0) // 最后一个参数0是设置该信号量的初始值。

(3)创建成功后,保存到自定义的变量中。

(4)不再使用时,记得sem_destroy(sem),及时释放系统资源。

无名信号量一般用于进程内通信,如果要在不同的进程间实现共享,必须在sem_init 时设置shared参数为1,并且该信号量的内存地址是进程间可见的。不过要实现进程间的信号量,直接使用有名信号量就好。

使用api步骤:

(1)sem_init,初始化信号量。

(2)sem_post,对信号量加一。

(3)sem_wait,阻塞等待信号量大于0。

(3)sem_trywait,如果信号量不大于0,会立即返回失败。

(4)sem_destroy,销毁信号量,释放系统资源。

4、unix相关标准

(1)POSIX: 是一种可移植操作系统接口,由大名鼎鼎的IEEE发布,该标准是为了提高UNIX环境的应用程序的可移植性。

(2)single UNIX specification:是POSIX.1标准的超集,定义了一些附加的接口。

(3)XSI:X/OPEN系统接口,XSI还定义了实现必须支持的POSIX.1的哪些可选部分才能认为是遵循XSI,可选部分包括文件同步、存储映射文件、存储操作、及线程接口,只有遵循XSI的实现才能称为UNIX操作系统。

5、管道

管道是UNIX系统最古老的IPC,具有两种局限性:半双工和管道只能在具有公共祖先的两个进程之间使用。每当在管道键入一个命令序列,让shell实行时,shell会为每一条命令单独创建一个进程,然后用管道将前一条命令进程的标准输出与后一条命令的标准输入相连接。

例如命令:ps -ef | grep helloworld,中间的符号“|”就是管道。

FIFO有时被称为命令管道,通过FIFO,不相关的进程也能交换数据。

由于管道已经很少被使用,所以只是大概学习了一下,主要知道了平时敲的命令其实很多都用到了管道,确实能带来很多方便。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值