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应用:多线程编程的主要内容,如果未能解决你的问题,请参考以下文章