linux应用:多线程编程

Posted 超凡东皇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)

运行如下:

以上是关于linux应用:多线程编程的主要内容,如果未能解决你的问题,请参考以下文章

linux下多线程编程

Linux多线程编程

多线程编程

linux应用:多线程编程

Linux系统应用编程 --- 多线程之线程回收

Linux系统应用编程 --- 多线程之线程回收