操作系统的本质是为了管理硬件资源,提供给应用程序统一的接口,使得应用程序可以直接使用硬件资源,而不需要过多关注底层硬件的细节。线程是应用程序中非常重要的概念,它可以让应用程序变得高效和可靠。在Linux系统中,线程也是重要的概念之一,它对应的就是轻量级进程(LWP)。Linux系统中线程的创建和销毁都比较容易,但是如何实现线程间的共享,则需要使用到一些技巧,其中之一就是句柄的应用。
创新互联公司网站建设由有经验的网站设计师、开发人员和项目经理组成的专业建站团队,负责网站视觉设计、用户体验优化、交互设计和前端开发等方面的工作,以确保网站外观精美、网站设计、成都网站制作易于使用并且具有良好的响应性。
句柄是一种抽象的概念,通常表示一些资源的标识符。在Linux系统中,许多资源都可以通过句柄来进行描述和处理,比如文件、套接字、管道等等。在多线程环境中,句柄被广泛应用在线程间的共享中,可以让不同的线程共享同一个句柄,从而实现资源的共享。
下面通过一个简单的例子来说明如何利用句柄实现线程间的共享。假设有两个线程,分别代表两个进程,要共享一个共享内存区域,代码如下:
“`
#include
#include
#include
#include
#include
#include
#include
#include
#define SHM_SIZE 1024
void *thread1(void *arg);
void *thread2(void *arg);
int shmid;
int mn(int argc, char **argv)
{
pthread_t tid1, tid2;
shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
if (shmid == -1) {
perror(“shmget”);
exit(EXIT_FLURE);
}
if (pthread_create(&tid1, NULL, thread1, NULL) != 0) {
perror(“pthread_create”);
exit(EXIT_FLURE);
}
if (pthread_create(&tid2, NULL, thread2, NULL) != 0) {
perror(“pthread_create”);
exit(EXIT_FLURE);
}
if (pthread_join(tid1, NULL) != 0) {
perror(“pthread_join”);
exit(EXIT_FLURE);
}
if (pthread_join(tid2, NULL) != 0) {
perror(“pthread_join”);
exit(EXIT_FLURE);
}
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror(“shmctl”);
exit(EXIT_FLURE);
}
exit(EXIT_SUCCESS);
}
void *thread1(void *arg)
{
void *shmaddr;
shmaddr = shmat(shmid, NULL, 0);
if (shmaddr == (void *)-1) {
perror(“shmat”);
exit(EXIT_FLURE);
}
printf(“Thread1 attach shared-memory\n”);
strcpy(shmaddr, “Hello, world!\n”);
pthread_exit(NULL);
}
void *thread2(void *arg)
{
void *shmaddr;
usleep(500000);
shmaddr = shmat(shmid, NULL, 0);
if (shmaddr == (void *)-1) {
perror(“shmat”);
exit(EXIT_FLURE);
}
printf(“Thread2 attach shared-memory\n”);
printf(“Message: %s\n”, (char *)shmaddr);
pthread_exit(NULL);
}
“`
上面的代码创建了两个线程,一个线程用来写入共享内存区域,另一个线程用来读取共享内存区域,并将读取到的内容打印出来。可以看到,两个线程都通过shmat函数获取共享内存区域的地址,从而可以对该共享内存进行读写操作。在这个例子中,shmat函数返回的就是共享内存区域的句柄,两个线程都拥有该句柄,并利用它来共享内存。
这个例子虽然简单,但也说明了句柄在Linux线程间共享中的重要性。句柄的应用使得不同的线程可以共享同一资源,从而提高了线程的利用率和系统的可靠性。当然,在使用句柄时,需要注意同步和错误处理的问题,否则可能会出现一些难以预料的问题。
成都网站建设公司-创新互联为您提供网站建设、网站制作、网页设计及定制高端网站建设服务!
From :
1.同一个线程内部,指令按照先后顺序执行;但不同线程之间的指令很难说清楚是哪一个先执行,在并况下,指令执行的先后顺序由内核决定。
如果运行的结果依赖于不同线程执行的先后的话,那么就会形成竞争条件,在这样的情况下,计算的结果很难预知,所以应该尽量避免竞争条件的形成。
2.最常见的解决竞争条件的方法是:将原先分离的两个指令构成一个不可分割的原子操作,而其他任务不能插入到原子操作中!
3.对
多线程
来说,同步指的是在一定时间内只允许某一个线程访问某个资源,而在此时间内,不允许其他线程访问该资源!
互斥锁
条件变量
读写锁
信号量
一种特殊的
全局变量
,拥有lock和unlock两种状态。
unlock的互斥锁可以由某个线程获得,一旦获得,这个互斥锁会锁上变成lock状态,此后只有该线程由权力打开该锁,其他线程想要获得互斥锁,必须得到互斥锁再次被打开之后。
1.互斥锁的初始化, 分为静态初始化和动态初始化.
2.互斥锁的相关属性及分类
(1) attr表示互斥锁的属性;
(2) pshared表示互斥锁的共享属性,由两种取值:
1)PTHREAD_PROCESS_PRIVATE:锁只能用于一个进程内部的两个线程进行互斥(默认情况)
2)PTHREAD_PROCESS_SHARED:锁可用于两个不同进程中的线程进行互斥,使用时还需要在进程共享内存中分配互斥锁,然后为该互斥锁指定属性就可以了。
互斥锁存在缺点:
(1)某个线程正在等待共享数据内某个条件出现。
(2)重复对数据对象加锁和解锁(轮询),但是这样轮询非常耗费时间和资源,而且效率非常低,所以互斥锁不太适合这种情况。
当线程在等待满足某些条件时,使线程进入睡眠状态;一旦条件满足,就换线因等待满足特定条件而睡眠的线程。
程序的效率无疑会大大提高。
1)创建
静态方式:pthread_cond_t cond PTHREAD_COND_INITIALIZER
动态方式:int pthread_cond_init(&cond,NULL)
Linux thread 实现的条件变量不支持属性,所以NULL(cond_attr参数)
2)注销
int pthread_cond_destory(&cond)
只有没有线程在该条件变量上,该条件变量才能注饥亩销,否则返回EBUSY
因为Linux实现的条件变量没有分配什么资源,所以注销动作只包括检查是否姿肢改有等待线程!(请参考条件变量的底层实现)
3)等待
条件等待:int pthread_cond_wait(&cond,&mutex)
计时等待:int pthread_cond_timewait(&cond,&mutex,time)
1.其中计时等待如果在给定时刻前条件没有被满足,则返回ETIMEOUT,结束等待
2.无论那种等待方式,都必须有一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait形成竞争条件!
3.在调用pthread_cond_wait前必须由本线程加锁
4)激发
激发一个等待线程:pthread_cond_signal(&cond)
激发所有等待线程:pthread_cond_broadcast(&cond)
重要的是,pthread_cond_signal不会存在惊群效应,也就是是它最多给一个等待线程发信号,不会给所有线程发信号唤醒,然后要求他们自己去争抢资源!
pthread_cond_broadcast() 唤醒所有正在pthread_cond_wait()的同一个条件变量的线程。注意:如果等待的多个现场不使用同一个锁,被唤迹判醒的多个线程执行是并发的。
pthread_cond_broadcast & pthread_cond_signal
1.读写锁比互斥锁更加具有适用性和并行性
2.读写锁最适用于对
数据结构
的读操作读操作次数多余写操作次数的场合!
3.锁处于读模式时可以线程共享,而锁处于写模式时只能独占,所以读写锁又叫做共享-独占锁。
4.读写锁有两种策略:强读同步和强写同步
强读同步:
总是给读者更高的优先权,只要写者没有进行写操作,读者就可以获得访问权限
强写同步:
总是给写者更高的优先权,读者只能等到所有正在等待或者执行的写者完成后才能进行读
1)初始化的销毁读写锁
静态初始化:pthread_rwlock_t rwlock=PTHREAD_RWLOCK_INITIALIZER
动态初始化:int pthread_rwlock_init(rwlock,NULL),NULL代表读写锁采用默认属性
销毁读写锁:int pthread_rwlock_destory(rwlock)
在释放某个读写锁的资源之前,需要先通过pthread_rwlock_destory函数对读写锁进行清理。释放由pthread_rwlock_init函数分配的资源
如果你想要读写锁使用非默认属性,则attr不能为NULL,得给attr赋值
int pthread_rwlockattr_init(attr),给attr初始化
int pthread_rwlockattr_destory(attr),销毁attr
2)以写的方式获取锁,以读的方式获取锁,释放读写锁
int pthread_rwlock_rdlock(rwlock),以读的方式获取锁
int pthread_rwlock_wrlock(rwlock),以写的方式获取锁
int pthread_rwlock_unlock(rwlock),释放锁
上面两个获取锁的方式都是阻塞的函数,也就是说获取不到锁的话,调用线程不是立即返回,而是阻塞执行,在需要进行写操作的时候,这种阻塞式获取锁的方式是非常不好的,你想一下,我需要进行写操作,不但没有获取到锁,我还一直在这里等待,大大拖累效率
所以我们应该采用非阻塞的方式获取锁:
int pthread_rwlock_tryrdlock(rwlock)
int pthread_rwlock_trywrlock(rwlock)
互斥锁只允许一个线程进入临界区,而信号量允许多个线程进入临界区。
1)信号量初始化
int sem_init(&sem,pshared, v)
pshared为0,表示这个信号量是当前进程的局部信号量。
pshared为1,表示这个信号量可以在多个进程之间共享。
v为信号量的初始值。
返回值
:
成功:0,失败:-1
2)信号量值的加减
int sem_wait(&sem):以原子操作的方式将信号量的值减去1
int sem_post(&sem):以原子操作的方式将信号量的值加上1
3)对信号量进行清理
int sem_destory(&sem)
关于linux 线程 共享 句柄的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
创新互联(cdcxhl.com)提供稳定的云服务器,香港云服务器,BGP云服务器,双线云服务器,高防云服务器,成都云服务器,服务器托管。精选钜惠,欢迎咨询:028-86922220。
新闻标题:Linux线程共享技巧:探讨句柄的应用(linux线程共享句柄)
网站路径:http://www.shufengxianlan.com/qtweb/news14/210264.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联