用互斥锁来管理交通
为了保护某段代码的安全,你需要创建互斥锁:
pthread_mutex_t a_lock = PTHREAD_MUTEX_INITIALIZER;
互斥锁必须对所有可能发生冲突的线程可见,也就是说它是一个全局变量。
PTHREAD_MUTEX_INITIALIZER 实际上是一个宏,当编译器看到它,就会插入创建互斥锁的代码。
红灯停。
你需要把第一盏红绿灯放在这段代码的开头,
pthread_mutex_lock() 只允许一个线程通过,其他线程运行到这行代码时必须等待。
绿灯行。
当线程到达代码的尾部就会调用
pthread_mutex_unlock() 把红绿灯调回绿灯,其他线程就能进入这段代码了:
既然你知道了怎么在代码中创建锁,也就能精确控制线程的行为了。
把 long 值传给线程函数
线程函数可以接收一个 void 指针作为参数,并返回一个 void 指针值。通常你希望把某个整型值传给线程,并让它返回某个整型值,一种方法是用 long ,因为它的大小和 void 指针相同,可以把它保存在 void 指针变量中。
练习
找到上锁的位置实非易事,而锁的位置会改变代码的运行方式。下面有两个不同版本的 drink_lots() 函数,它们以不同方式为代码上了锁。两段代码都用互斥锁来保护 beers 变量的安全,并在退出前显示了 beers 值。由于它们在不同的位置使用了锁,因此在屏幕上输出了不同结果。你能弄清哪段代码对应哪个版本吗?
练习解答
找到上锁的位置实非易事,而锁的位置会改变代码的运行方式。下面有两个不同版本的 drink_lots() 函数,它们以不同方式为代码上了锁。两段代码都用互斥锁来保护 beers 变量的安全,并在退出前显示了 beers 值。由于它们在不同的位置使用了锁,因此在屏幕上输出了不同结果。请弄清哪段代码对应哪个版本。
恭喜!你已经(快要)看完这本书了。打开一瓶啤酒,庆祝一下吧!
是时候决定你将成为哪种类型的 C 程序员了。写纯 C 代码的 Linux 黑客?还是为 Arduino 那种小装置写嵌入式 C 的匠人?或是转而成为一名使用 C++的游戏开发人员?或使用 Objective-C 的 Mac 及 iOS 程序员?
无论你的选择是什么,你都已经成为了 C 社区的一份子。在这里,你们使用同一种语言,并深深热爱着它。这种语言创建的软件比其他任何语言都要多;它是整个互联网和几乎所有操作系统的基础;几乎所有其他语言都是用它写的;几乎所有电子设备的处理器都可以用它来编程,大到飞机卫星,小到手表手机。
欢迎你!一年级 C 黑客!这里没有蠢问题**问:为了支持多线程,我的计算机必须有多个处理器吗?答:不必。绝大多数计算机都使用多核处理器。也就是说 CPU 中有一些小型处理器,它们可以一次做几件事情。即便代码运行在一台单核/单处理器的计算机上,也还是能运行多线程程序。问:怎么运行?答:操作系统会在多个线程之间快速地切换,看起来就好像在同时做多件事。问:线程能让程序变得更快吗?答:也不一定,尽管线程可以帮助你利用机器上更多的处理器和核,但你还是需要控制代码中锁的数量,如果用了太多锁,代码可能会像单线程程序一样慢。问:怎样设计高效的多线程程序?答:减少线程需要访问的共享数据的数量。如果线程无需访问很多共享数据,那么多个线程等一个线程的情况就很少出现,速度会大大提高。问:线程要比进程快?答:通常是这样,因为创建进程要比创建线程花更多时间。问:听说互斥锁会引发“死锁”,那是什么玩意儿?答:假设你有两个线程,它们都想得到互斥锁 A 和 B。倘若第一个线程得到了 A,第二个线程得到了 B,这两个线程就会陷入死锁。因为第一个线程无法得到 B,第二个线程无法得到 A,它俩都停滞不前。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论