线程控制(一)

1. 线程执行顺序问题

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>void *thread1(void *);
void *thread2(void *);pthread_key_t key;void *thread1(void *arg){int a = 1, *tsd = &a;pthread_t thid2;printf("thread1 %lu is running\n", pthread_self());pthread_setspecific(key, tsd);pthread_create(&thid2, NULL, thread2, NULL);sleep(3);  //---2tsd = (int *)pthread_getspecific(key);printf("thread1 %lu returns %d\n", pthread_self(), *tsd);return (void *)0;
}void *thread2(void *arg){int a = 5, *tsd = &a;printf("thread2 %lu is running\n", pthread_self());pthread_setspecific(key, (int *)tsd);tsd = (int *)pthread_getspecific(key);printf("thread2 %lu returns %d\n", pthread_self(), *tsd);//tsd is a pointerreturn (void *)0;
}int main(int argc, char const *argv[])
{pthread_t thid1;printf("main thread is running\n");pthread_key_create(&key, NULL);pthread_create(&thid1, NULL, thread1, NULL);sleep(5);  //---1pthread_key_delete(key);printf("main thread exit\n");return 0;
}

1)代码1、2处都不注释,运行结果:

 test1

2)代码中2处注释掉,1保留,运行结果:

 est2

3)代码中1处注释掉,2保留,运行结果:

test3


奇怪的现象发生了!!

我们会发现,在第3种情况中,竟然只有main函数中的内容输出了,而子线程好像没有运行。为什么呢?原来,在用户没有设定线程间的调度策略时,系统默认采取基于时间片轮转的调度策略。此时,子线程要在主线程空闲的条件下才会执行,假设主线程一直在工作,那么子线程没有机会运行,直到主线程退出。

然而,由于线程间共享资源,主线程的退出会影响到该进程下的所有线程,所以子线程就永远没有机会执行,也就造成了第3种只有main函数中的内容输出了。

而使用sleep函数会让程序挂起一段时间,让子进程得到运行的机会,所以前两种情况所有函数中内容都有输出,只是顺序不同而已。当然,子线程的执行顺序也是不确定的,这就要看操作系统的具体分配了。


2. 条件变量的使用

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
pthread_cond_signal(pthread_cond_t *cond);

pthread_cond_wait会先解锁mutex指向的互斥锁,再将cond指向的条件变量阻塞,直到该条件变量值改变,再将mutex指向的互斥锁加锁。

pthread_cond_signal则用来激活一个正在等待条件成立的线程,使该线程继续运行。与pthread_cond_wait函数配合使用。

使用pthread_cond_wait方式如下:

pthread _mutex_lock(&mutex)
while(线程执行的条件是否成立)pthread_cond_wait(&cond, &mutex);
线程执行
pthread_mutex_unlock(&mutex);

为什么要在while内判断呢?

因为在等待运行的程序会有很多,所以需要竞争才能得到下一次运行的权利,而在pthread_cond_signal或者pthread_cond_broadcast执行后,wait虽然成功了,但是当前线程不一定就能竞争到运行的权利,可能被其他更加“强大”的线程抢到手,所以需要不断循环来判断是达到了可以执行的条件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/381964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Codeforces Round #324 (Div. 2) B. Kolya and Tanya

思路&#xff1a;因为题目说只要存在组ai??ai??n??ai??2n?≠?6就令人满意&#xff0c;也就是不满意的情况就是所有ai??ai??n??ai??2n?都等于6那就用所有的情况减去不满意的情况&#xff0c;总结: 直接用二分幂不知道为什么wa的要死&#xff0c;看到别人的题…

拓扑排序的题目集合

【HDU】1285确定比赛名次2094产生冠军2647Reward3342Legal or Not1811Rank of Tetris 拓扑并查集3231 Box Relations 三维拓扑【POJ】1094 Sorting It All Out Floyd拓扑2367 Genealogical tree3660 Cow Contest3687 Labeling Balls 神奇的拓扑1128Frame Stacking DFS版拓扑…

edward_mj退役经验帖

考完试了&#xff0c;也是时候补上退役帖了。考虑了一阵要怎么写&#xff0c;鉴于本文的目的主要是希望给后来的校队成员或者想参加这个竞赛的同学一个借鉴&#xff0c;最后还是决定用Q&A的形式。打ACM/ICPC有什么好处我觉得确切而言应该问把时间花在这上面有什么好处。提升…

C++学习笔记(一)

本文主要内容为C下的输入输出函数以及for循环中的C11新特性。 一、输入输出函数 1. cin cin 遇到 空格、回车、Tab结束输入&#xff0c; 且会将读到的空格、回车、Tab 丢弃&#xff0c;例&#xff1a; #include<iostream> using namespace std;int main(void) {char a…

为了更好——关于博客搬迁的说明

一开始没准备在网易安家的&#xff0c;可是由于博客和邮箱都在此处&#xff0c;访问会更加方便&#xff08;所以就稀里糊涂在这里安了家&#xff09;&#xff0c;但是后来发现网易的博客对用户并不友好&#xff08;广告低栏的注册&#xff09;&#xff0c;寻寻觅觅找了很多博客…

C++学习笔记(二)

本文将主要介绍const关键字的使用。 首先&#xff0c;说一下const是什么&#xff1a; const修饰的数据类型是指常类型&#xff0c;常类型的变量或对象的值是不能被更新的。 然后&#xff0c;我们来看一下这四处声明&#xff1a; const int a 1; //code1 const int *p &am…

关于Github的那点事儿

今天突然发现无法从本地git push到远程仓库了&#xff08;然而事实是网有点卡&#xff0c;github官网没更新过来&#xff0c;然而……ssh-key已经删了….&#xff09;&#xff0c;所以又重新添加ssh-key。 ssh-keygen -t rsa cat ~/.ssh/id_rsa.pub 将显示的内容粘贴到github…

C++学习笔记(三)

1. 引用变量 引用是已定义变量的别名&#xff0c;若使用int & x a;&#xff0c;即将x作为a的引用&#xff0c;其中的&不是地址运算符&#xff0c;而是类型标识符的一部分。事实上&#xff0c;x与a指向的是同一块内存空间&#xff0c;对x进行操作即对a进行操作。必须在…

Rabbits —— HDU-6227

题意&#xff1a; 有n只兔子在不同的位置&#xff0c;任意一只兔子可以跳到其余任两只兔子&#xff08;必须保证它们中间有空位&#xff09;中间&#xff0c;问最多可移动多少次&#xff1f; 思路&#xff1a; 可看作从任一侧的兔子向中间插空&#xff0c;因此可以将所有兔子…

uva 10570——Meeting with Aliens

题意&#xff1a;输入1-n的排列&#xff0c;每次可以交换两个整数。用最少的次数把排列变成1-n的环状序列。 思路&#xff1a;枚举贪心。依次枚举环上所有的点&#xff0c;正序一遍&#xff0c;倒序一遍&#xff0c;然后贪心求的所需的最小步数&#xff08;贪心策略是1与1号交换…

I/O复用之 epoll

epoll 系统调用 1. 内核事件表 epoll使用一系列函数来完成任务&#xff0c;把用户关心的文件描述符中的事件放到内核里的一个事件表中&#xff0c;因此不用像select、poll那样每次调用都要重复传入文件描述符集或事件表。epoll需要一个文件描述符来唯一标识该事件表&#xff0…

uva 1153—— Keep the Customer Satisfied

题意&#xff1a;有n个工作&#xff0c;已知每个工作的开始时间和结束时间&#xff0c;问最多能完成多少工作。 思路&#xff1a;贪心。要想使得最后的结果最佳&#xff0c;那么开始的晚的&#xff0c;要在最后来做。在此基础上&#xff0c;需要保证先做开始的早的&#xff08;…

I/O复用之 EPOLLONESHOT 事件

EPOLLONESHOT 事件 EPOLLONESHOT 事件 1. 使用EPOLLONESHOT的原因及优点2. recv返回值 及 与errno的配合使用3. 示例程序 1. 使用EPOLLONESHOT的原因及优点 即使使用ET模式&#xff0c;一个socket上的某个事件还是可能被触发多次。比如&#xff1a;一个线程在读取完某个sock…

uva 1612——Guess

题意&#xff1a;有n个选手参加比赛&#xff0c;比赛有3个题目&#xff0c;每个选手每个题目都有一个评测之前的于得分&#xff0c;当通过题目时才可以得到相应分数&#xff0c;否则为0&#xff0c;然后按照得分排名&#xff0c;id小的排在前面&#xff0c;现在给定选手的于得分…

uva 1611——Crane

题意&#xff1a;给定一个1-n的排序&#xff0c;每次可以选定一个偶数长的序列&#xff0c;然后交换前一部分和后一部分&#xff0c;使得最后的成为1-n的序列。求最后的次数和每次的策略。 思路&#xff1a;贪心。每次贪心的策略都是把i放到第i位置上&#xff0c;交换的时候找到…

【世界上最美丽的7张太阳照片】

【世界上最美丽的&#xff17;张太阳照片】 文章来源:http://ms.blogger.cn/peon/posts/1634.aspx转载于:https://www.cnblogs.com/paulzhu/archive/2004/02/24/1572.html

uva 11925——Generating Permutations

题意&#xff1a;给定一个1-n的排列&#xff0c;用不超过2*n2的操作把他变成升序。每次操作只有两种&#xff0c;一种是交换前两个元素&#xff0c;另外一种是把最后一个元素放到最后一位。 思路&#xff1a;贪心。用双端队列来保存数据&#xff0c;每次当v[0]>v[1]&&am…

二维map —— HDU1263

水果 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8752 Accepted Submission(s): 3482Problem Description 夏天来了~~好开心啊,呵呵,好多好多水果~~ Joe经营着一个不大的水果店.他认为生存之道就是经营最…

uva 11491——Erasing and Winning

题意&#xff1a;给定一个n位的整数&#xff0c;要求从中去掉k位&#xff0c;使得剩下的数字最大。 思路&#xff1a;单调队列。在满足删除的数等于k 的前提下求一个不敌减的序列。 code&#xff1a; #include <iostream> #include <cstdio> #include <cmath>…

工作组和域的区别

局域网上的资源需要管理&#xff0c;“域”和“工作组”就是两种不同的网络资源管理模式。那么二者有何区别呢&#xff1f;看了这篇文章&#xff0c;您就会明白了。工作组 Work Group在一个网络内&#xff0c;可能有成百上千台电脑&#xff0c;如果这些电脑不进行分组&#xff…