Linux 多线程编程是一种复杂的编程方式,它与传统的单线程编程方式有着明显的不同。在多线程编程中,一个程序可以同时执行多个任务,这些任务可以在一个或者多个进程间进行切换。但是,多线程编程也面临着许多挑战,比如全局变量数据共享问题。
创新互联公司-专业网站定制、快速模板网站建设、高性价比靖西网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式靖西网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖靖西地区。费用合理售后完善,10余年实体公司更值得信赖。
在本文中,我们将探讨在 Linux 多线程编程中的全局变量问题,包括定义全局变量、全局变量的作用域以及如何合理使用全局变量。
定义全局变量
在多线程编程中,我们通常需要在不同的线程享数据。全局变量是一种最常用的共享数据路径,因为它可以被所有进程访问。在 Linux 中,我们可以通过将变量定义在文件的头文件中来定义全局变量。
例如:
“`c
int global_var;
“`
在这个例子中,我们定义了一个名为 global_var 的整型变量作为全局变量。在多个线程之间,可以通过访问这个全局变量来共享数据。
全局变量的作用域
在使用全局变量时需要注意作用域的问题。
在程序中,有不同的作用域范围,从而影响了变量的可见性。在多线程编程中,我们需要将全局变量的作用域限定在各个线程中,以避免线程之间的竞争问题。
比如,我们可以在不同的函数中定义同名的全局变量。这些变量之间是没有任何影响的,因为它们的作用域范围不同。
例如,我们在 file1.c 中定义了一个全局变量:
“`c
int num1 = 10;
“`
在另一个文件 file2.c 中,我们定义了一个同名的全局变量:
“`c
int num1 = 20;
“`
在这种情况下,num1 可以分别被 file1.c 和 file2.c 中的代码访问,但它们之间没有任何关系。
在多线程编程中,我们可以通过将全局变量定义为静态,来限制其作用域只在一个线程中。
例如:
“`c
static int global_var;
“`
这个定义告诉编译器,全局变量 global_var 只能在当前文件的作用域范围内使用。这可以避免在多个线程之间出现全局变量的竞争问题。
合理使用全局变量
全局变量虽然方便,但在多线程编程中,使用全局变量也有可能引起竞争问题。在多个线程同时修改一个全局变量时,有可能导致数据错乱或者程序崩溃。
因此,在多线程编程中,我们需要合理地使用全局变量,尽可能避免在不同线程中修改同一个全局变量。一些常用的方法包括:
1. 在不同线程之间传递变量通过参数传递的方式,而不是使用全局变量。
2. 如果必须使用全局变量,需要使用加锁技术来保护全局变量的访问。只有在一个线程获取到了锁的情况下,才能修改这个全局变量。
3. 在编写程序时,应当尽可能地避免使用全局变量,采用局部变量来代替。
结论
在 Linux 多线程编程中,全局变量的问题是需要注意的。全局变量可以方便地共享数据,但同时也需要注意变量的作用域和安全性。我们需要在编写程序时,根据实际情况合理地使用全局变量,尽可能地避免出现竞争问题。
相关问题拓展阅读:
使用条件变量更大的好处是可以避免忙等。相当与多线程中的信号。
条件变量是线程中的东西就是等待某一条件的发生和信号一样
以下是说明
,条件变量使我们可以睡眠等待某种条件出现。
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使”条件成立”(给出条件成立信号)。为了防止槐凳竞争,条件变量的使用总是和一个互斥锁结合在一起。
条件变量类型为pthread_cond_t
创建和注销
条件变量和互斥锁一样,都有静态动态两种创建方式,静态方式使用PTHREAD_COND_INITIALIZER常量,如下:
pthread_cond_t
cond=PTHREAD_COND_INITIALIZER
动态方式调用pthread_cond_init()函数,API定义如下:
int
pthread_cond_init(pthread_cond_t
*cond,
pthread_condattr_t
*cond_attr)
尽管POSIX标准中为条件变量定义了属性,但在LinuxThreads中没有实现,因此cond_attr值通常为NULL,且被忽略。
注销一个条件变量需要调用pthread_cond_destroy(),只有在没有线程在该条件变量上等待的时候才能注销这个条件变量,否则返回EBUSY。API定义如下:
int
pthread_cond_destroy(pthread_cond_t
*cond)
等待和激发
int
pthread_cond_wait(pthread_cond_t
*cond,
pthread_mutex_t
*mutex)
int
pthread_cond_timedwait(pthread_cond_t
*cond,
pthread_mutex_t
*mutex,
const
struct
timespec
*abstime)
等待条件有两种方式:无条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间1970年1月1日0时0分0秒。
使用绝对时间而非相对时间的优点是吵明。如果函数提前返回(很可能因为捕获了一个信号,)
无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的竞争条件(Race
Condition)。mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。
激发条件有两种形式,pthread_cond_signal()激活铅碰旅一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个;而pthread_cond_broadcast()则激活所有等待线程。
其他
pthread_cond_wait()和pthread_cond_timedwait()都被实现为取消点,因此,在该处等待的线程将立即重新运行,在重新锁定mutex后离开pthread_cond_wait(),然后执行取消动作。也就是说如果pthread_cond_wait()被取消,mutex是保持锁定状态的,因而需要定义退出回调函数来为其解锁。
在网上看到这个系列的
文章对Linux下的POSIX线程编程方法阐述的十分的清晰,小弟目前关心要学习线程同步中的条件变量的使用方法,转载一下呵呵……
互斥对象是线程程序必需的工具,但它们并非万能的。例如,如果线程正在侍者等待共享数据内某个条件出现,那会发生什么呢?代码可以反复对互斥对象锁定和解锁, 以检查值的任何变化。同时,还要快速将互斥对象解锁,以便其它线程能够进行任何必需的更改。这是一种非常可怕的方法,因为线程需要在合理的时间范围内频繁 地循环检测变化。
在每次检查之间,可以让调用线程短暂地进入睡眠,比如睡眠三秒钟,但是因此线程代码就无法最快作出响应。真正需要的是这样一种方法,当线程在等待满足某些 条件时使线程进入睡眠状态。一旦条件满足,还需要一种方法以唤醒因等待满足特定条件而睡眠的线程。如果能够做到这一点,线程代码将是非常高效的,并且不会 占用宝贵的互斥对象锁。这正是 POSIX 条件变量能做的事!
本文是 POSIX 线程三部曲系列的最后一部分,Daniel 将详细讨论如何使用条件变量。条件变量是 POSIX 线程结构,可以让您在遇到某些条件时“唤醒”线程。可以将它们看作是一种线程安全的信号发送。Daniel 使用目前您所学到的知识实现了一个多线程工作组应用程序,本文将围绕着这一示例而进行讨论。
条件变量详解
在 上一篇文章结 束时,我描述了一个比较特殊的难题:如果线程正在等待某个特定条件发生,它应该如何处理这种情况?它可以重复对互斥对象锁定和解锁,每次都会检查共享数据 结构,以查找某个值。但这是在浪费时间和资源,而且这种繁忙查询的效率非常低。解决这个问题的更佳方法是使用 pthread_cond_wait() 调用来等待特殊条件发生。
了解 pthread_cond_wait() 的作用非常重要 — 它是 POSIX 线程信号发送系统的核心,也是最难以理解的部分。
首先,让我们考虑以下情况:线程为查看已链接列表而锁定了互斥对象,然而该列表恰巧是空的。这一特定线程什么也干不了 — 其设计意图是从列表中除去节点,但是现在却没有节点。因此,它只能:
锁定互斥对象时,线程将调用 pthread_cond_wait(&mycond,&mymutex)。pthread_cond_wait() 调用相当复杂,因此我们每次只执行它的一个操作。
pthread_cond_wait() 所做的之一件事就是同时对互斥对象解锁(于是其它线程可以修改已链接列表),并等待条件 mycond 发生(这样当 pthread_cond_wait() 接收到另一个线程的氏袜“信号”时,它将苏醒)。现在互斥对象已被解锁,其它线程可以访问和修改已链接列表,可能还会添加项。
此 时,pthread_cond_wait() 调用还未返回。对互斥对象解锁会立即发生,但等待条件 mycond 通常是一个阻塞操作,这意味着线程将睡眠,在它苏醒之前不会消耗 CPU 周期。这正是我们期待发生的情况。线程将一直睡眠,直到特定条件发生,在这期间不会发生任何浪费 CPU 时间的繁忙查询。从线程的角度来看,它只是在等待 pthread_cond_wait() 调用返回。
现在继续说明,假设 另一个线程(称作“2 号线程”)锁定了 mymutex 并对已链接列表添加了一项。在对互斥对象解锁之后,2 号线程会立即调用函数 pthread_cond_broadcast(&mycond)。此操作之后,2 号线程将使所有等待 mycond 条件变量的线程立即苏醒。这意味着之一个线程(仍处于 pthread_cond_wait() 调用中)现在将苏醒。
现 在,看一下之一个线程发生了什么。您可能会认为在 2 号线歼谈激程调用 pthread_cond_broadcast(&mymutex) 之后,1 号线程的 pthread_cond_wait() 会立即返回。不是那样!实际上,pthread_cond_wait() 将执行最后一个操作:重新锁定 mymutex。一旦 pthread_cond_wait() 锁定了互斥对象,那么它将返回并允许 1 号线程继续执行。那时,它可以马上检查列表,查看它所感兴趣的更改。
关于linux多线程 全局变量的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
成都创新互联科技有限公司,是一家专注于互联网、IDC服务、应用软件开发、网站建设推广的公司,为客户提供互联网基础服务!
创新互联(www.cdcxhl.com)提供简单好用,价格厚道的香港/美国云服务器和独立服务器。创新互联成都老牌IDC服务商,专注四川成都IDC机房服务器托管/机柜租用。为您精选优质idc数据中心机房租用、服务器托管、机柜租赁、大带宽租用,可选线路电信、移动、联通等。
当前标题:深入理解Linux多线程编程中的全局变量问题(linux多线程全局变量)
标题来源:http://www.shufengxianlan.com/qtweb/news20/38770.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联