- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Linux系统的多线程编程1深入
?一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程一、什么是多线程?
? ? ? 当我自己提出这个问题的时候,我还是很老实的拿着操作系统的书,按着上面的话敲下“为了减少进程切换和创建开销,提高执行效率和节省资源,我们引入了线程的概念,与进程相比较,线程是CPU调度的一个基本单位。”? ? ? 形象点的举个例子说:一个WEB服务器可以同时接收来自不同用户的网页访问请求,显然服务器处理这些网页请求都是通过并发进行的否则将会造成用户等待时间长或者响应效率低等问题。如果在服务器中使用进程的办法来处理来自不同网页访问请求的话,我们可以用创建父进程以及多个子进程的方法,然而这样会花费很大的系统开销和占用较多的资源,因此这样会较大的限制了访问服务器的用户数量。
? ? ??使用多线程的理由之一是和进程相比,它是一种非常节俭的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种昂贵的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间
? ? ??使用多线程的理由之二是线程间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改
二、互斥锁
? ? ? 正如上面所说的,如果两个线程同时对一块内存进行读写或者对向同一个文件写数据,那么结果是难以设想的。正因为如此,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为 互斥锁 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
?例如int *a ?int *b ?分别指向两块内存,上面的值分别初始化为(200, 100) 线程A执行这样的一个操作:将*a的值减少50,*b的值增加50.
?线程B执行:打印出(a 跟 b 指向的内存的值的和)。
? ? ? 如果串行运行:A: *a -= 50; *b += 50; ?B: printf(%d\n, *a + *b); ?
? ? ? 如果并发执行,则有可能会出现一下调度:*a -= 50; printf(%d\n, *a + *b);?*b += 50;
? ? ? 因此我们可以引入互斥量,在对共享数据读写时进行锁操作,实现对内存的访问以互斥的形式进行。
? ? ??
#include stdio.h
#include unistd.h
#include pthread.h
?
int?a = 200;
int?b = 100;
pthread_mutex_t lock;
?
void* ThreadA(void*)
{
pthread_mutex_lock(lock);????????? //锁
a -= 50;
sleep(5);????????????????????????????????????? //执行到一半 使用sleep 放弃cpu调度
b += 50;
pthread_mutex_unlock(lock);
}
?
void* ThreadB(void*)
{
sleep(1);??????????????????????????? //放弃CPU调度 目的先让A线程运行。
pthread_mutex_lock(lock);
printf(%d\n, a + b);
pthread_mutex_unlock(lock);
}
?
int?main()
{
pthread_t tida, tidb;
pthread_mutex_init(lock, NULL);
pthread_create(tida, NULL, ThreadA, NULL);
pthread_create(tidb, NULL, ThreadB, NULL);
pthread_join(tida, NULL);
pthread_join(tidb, NULL);
return?1;
} ??以上输出为300 ?去掉锁操作 ?输出为250。
三、信号量? ? ??
?
? 作用域 上锁时 信号量 进程间或线程间(linux仅线程间) 只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减一。若value值不大于0,则sem_wait阻塞,直到sem_post释放后value值加一 互斥锁 线程间 只要被锁住,其他任
文档评论(0)