进程与线程的概念

本文通过一个音乐播放器的例子,解释了进程和线程的概念。在单线程程序中,读取按键和播放音乐必须顺序执行,可能导致播放不流畅。通过引入多线程,可以将读取按键和播放音乐任务分开,各自独立运行,提高程序效率。全局变量g_key用于线程间通信,使得按键线程能控制音乐线程的播放状态,实现音乐播放的平滑切换。这种方法减少了进程间通信的开销,优化了资源利用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进程、线程的概念

假设我们写一个音乐播放器,在播放音乐的同时会根据按键选择下一首歌。把事情简化为 2 件事:发送
音频数据、读取按键。那可以这样写程序:

int main(int argc, char **argv)
{
	int key;
	while (1)
	{
		key = read_key();
		if (key != -1)
		{
			switch (key)
			{
				case NEXT:
					select_next_music(); // 在 GUI 选中下一首歌
					break;
			}
		}
		else
		{
			send_music();
		}
	}
	return 0;
}

这个程序只有一条主线,读按键、播放音乐都是顺序执行。
无论按键是否被按下, read_key 函数必须马上返回,否则会使得后续的 send_music 受到阻滞导致音乐
播放不流畅。
读取按键、播放音乐能否分为两个程序进行?可以,但是开销太大:读按键的程序,要把按键通知播放
音乐的程序,进程间通信的效率没那么高。
这时可以用多线程之编程,读取按键是一个线程,播放音乐是另一个线程,它们之间可以通过全局变量
传递数据,示意代码如下:

int g_key;
void key_thread_fn()
{
	while (1)
	{
		g_key = read_key();
		if (g_key != -1)
		{
			switch (g_key)
			{
				case NEXT:
					select_next_music(); // 在 GUI 选中下一首歌
					break;
			}
		}
	}
}
void music_fn()
{
	while (1)
	{
		if (g_key == STOP)
			stop_music();
		else
		{
			send_music();
		}
	}
}
int main(int argc, char **argv)
{
	int key;
	create_thread(key_thread_fn);
	create_thread(music_fn);
	while (1)
	{
		sleep(10);
	}
	return 0;
}

这样,按键的读取及 GUI 显示、音乐的播放,可以分开来,不必混杂在一起。
按键线程可以使用阻塞方式读取按键,无按键时是休眠的,这可以节省 CPU 资源。
音乐线程专注于音乐的播放和控制,不用理会按键的具体读取工作。
并且这 2 个线程通过全局变量 g_key 传递数据,高效而简单。
在 Linux 中:资源分配的单位是进程,调度的单位是线程。
也就是说,在一个进程里,可能有多个线程,这些线程共用打开的文件句柄、全局变量等等。
而这些线程,之间是互相独立的,“同时运行”,也就是说:每一个线程,都有自己的栈。如下图示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值