linux应用:多线程编程

 线程在linux应用开发中是非常常用的,因为有些功能需要实时响应,而有些功能比较耗时,从而引入了并发的概念,即任务调度与时间片轮转,目的只有一个:更高效的利用cpu。那么如果不用线程用别的成吗,有没有其它的可取代线程的呢,比如进程、比如定时器?单纯从功能上说是可以的,但是严格意义上来说没有什么能取代多线程的地位。

一、线程跟进程比较:

1、线程是程序最基本的运行单位,也是参与系统调度的基本单位,而进程不能直接运行

2、线程间切换的开销比进程间切换开销小,创建的速度也比进程创建速度快的多

3、系统为进程必须分配独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段

4、线程彼此之间使用相同的地址空间,共享大部分数据,因此多线程间支持多种通讯交互方式

5、进程就相当于不同应用程序,通讯估计只能用socket套接字了吧

总之,线程包含在进程中,是参与系统调度的基本单位,而进程相当于是一个容器,有应用程序就必须有一个进程,一个进程则至少包含一个线程,嗯,就是这么回事。

二、线程与软件定时器比较

1、定时器是定时周期性处理的,而线程是基于系统调度的(相当于有第三方监管)

2、定时器其实是轮询消息队列中的消息,然后轮询处理,遇到耗时的一点办法都没有

3、定时器能处理的线程基本都能处理,而线程能处理的定时器不一定能处理

如果按上面这么说也许有人会问,那是不是软件定时器就没有存在的价值了,非也,非也,软件定时器简单啊,用起来很方便,尤其处理一些跟时间相关的周期性任务,而线程遇到问题比较难排查,比如cpu资源抢占,容易发生死锁,时间片不可控等等。

三、多线程编程

光说不练假把式,我还是喜欢直接上代码,在代码中锤炼...

需要注意的有以下两点:

①、需要包含 <pthread.h>头文件,这个文件包含了线程操作相关的API

②、编译时需要加-lpthread参数,使用-l 选项指定链接库pthread,因为pthread不在 gcc的默认链接库中,所以需要手动指定。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>

pthread_t tid;
pthread_attr_t attr;
	
static void *hello_thread(void *arg)
{
	//while(1)
	{	//打印当前线程id
		printf("hello thread! Id:%ld\n", pthread_self());
		
		printf("arg:%d\n", *(int*)arg);
		
		sleep(1);//当前线程挂起1s
	}
	 return (void *)0; 
}
 
int main(int argc, char *argv[])
{
	int ret;
	size_t stacksize;
	
	/* 对 attr 对象进行初始化 */
	pthread_attr_init(&attr);
	/* 获取堆栈大小 默认为 8388608 byte */
	ret =  pthread_attr_getstacksize(&attr, &stacksize);
	if(ret != 0){
		fprintf(stderr, "pthread_attr_getstacksize failed: %s\n", strerror(ret));
		exit(-1);
	}
	printf("init stacksize = %d\n", stacksize);

	/* 设置栈大小为 4K, 最小为 16384 byte */
	ret =  pthread_attr_setstacksize(&attr, 2 * 8 * 1024);
	if(ret != 0){
		fprintf(stderr, "pthread_attr_setstacksize failed: %s\n", strerror(ret));
		exit(-1);
	}
	/* 获取堆栈大小 */
	ret =  pthread_attr_getstacksize(&attr, &stacksize);
	if(ret != 0){
		fprintf(stderr, "pthread_attr_getstacksize failed: %s\n", strerror(ret));
		exit(-1);
	}
	printf("stacksize = %d\n", stacksize);
	
	/* 创建新线程 */
	int arg = 123;//arg参数,即hello_thread函数的入口参数
	ret = pthread_create(&tid, &attr, hello_thread, &arg);
	if (ret) {
		fprintf(stderr, "pthread_create error: %s\n", strerror(ret));
		exit(-1);
	}
	/* 获取当前线程也就是主线程id与子线程id */
	printf("main thread id:%ld, sub thread id:%ld\n", pthread_self(), tid);
	
	/* 等待新线程终止 */
	ret = pthread_join(tid, NULL);
	if (ret) {
		fprintf(stderr, "pthread_join error: %s\n", strerror(ret));
		exit(-1);
	}
	/* 销毁 attr 对象 */
	pthread_attr_destroy(&attr);
	printf("all thread exit!\n");
	exit(0);
}


Makefile文件:

CC=g++
CFLAGS=-Wall -g -pthread -DDEBUG
LDFLAGS=
LIBS=
NAME=test

all: test

test: *.cpp
	$(CC) -o $@ $(CFLAGS) $^ $(LIBS)

clean:
	rm -rf *.o $(NAME)

运行如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东皇※太一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值