多线程

使用多线程的理由:
① 和进程相比,其为一很节俭的多任务操作方式,启动一新进程须为其分配独立地址空间,建立众多数据表来维护代码段、数据段和堆栈段,是一种昂贵多任务工作方式;运行于一进程中多个线程,它们间使用相同地址空间,线程间切换耗时远远小于进程,据统计一进程开销约是一线程开销30倍(fork代码段共享,数据段、堆栈段均不共享,线程间全部共享)
② 线程间方便通信机制,对不同进程,起具有独立数据空间,要进行数据传递只能通过进程间通信方式,这些方式费时不便;线程由于共享数据空间,所以一线程数据可直接为其它线程所用,快捷方便(如定义全局变量,进程中所有线程均可看到)
③ 使多CPU系统更加有效,OS会保证当线程数不大于CPU数时,不同线程运行于不同CPU上
Linux系统下多线程遵循POSIX线程接口,称pthread,编写需使用头文件pthread.h,链接需使用库libpthread.a
——————/创建线程
#include <pthread.h>
int pthread_create(pthread_t * tidp,const pthread_attr_t *attr,void *(*start_rtn)(void),void *arg)
tidp:线程id
attr:线程属性(通常为空)
start_rtn:线程要执行的函数
arg:start_rtn的参数
# gcc filename –lpthread //因gcc编译,默认只用c库
——————/等待线程
int pthread_join(pthread_t tid,void **rval_ptr)
功能:等待指定线程终止(进程等待线程、线程等待线程)
Rval_ptr:参考thread_exit.c
——————/线程退出
如进程中任一线程调用exit或_exit,则整个进程终止,线程正常退出方式有:
(1) 线程从启动例程返回
(2) 线程被另一进程终止
(3) 线程自己调用pthread_exit
void pthread_exit(void * rval_ptr)
Rval_ptr:参考thread_exit.c
——————/线程标识
pthread_t pthread_self(void)
功能:获得当前线程id,参考thread_id.c
——————/线程清除
线程终止有两种情况:正常终止和非正常终止;线程主动调用pthread_exit或从线程函数return都使线程正常退出,该退出方式可预见;非正常终止是线程在其他线程干预下,或由于自身运行出错(如访问非法地址)而退出,该退出方式不可预见;不论可预见线程终止或异常终止,都存在资源释放问题
从pthread_cleanup_push调用点到pthread_cleanup_pop之间终止动作(包括调用pthread_exit()和异常终止,不包括return)都将执行pthread_cleanup_push所指定清理函数
void pthread_cleanup_push(void (*rtn)(void *),void *arg)
功能:将清除函数压入清除栈
Rtn:清除函数 Arg:清除函数参数
void pthread_cleanup_pop(int execute)
功能:将清除函数弹出清除栈
参数:是否在弹出清理函数同时执行清理函数,非0执行,0不执行,参考thread_clean.c
——————/
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
void *thread(void *str)
{
    int i;
    for (i = 0; i < 2; ++i)
    {
        sleep(2);
        printf( "in thread : %d\n" , i );
    }
    return NULL;
}

int main()
{
    pthread_t pth;
    int i;
    pthread_create(&pth, NULL, thread, NULL);
    printf("main will block\n");
    pthread_join(pth, NULL);	//思考去掉该行后执行结果?
    printf("thread exit\n");

    for (i = 0; i < 2; ++i)
    {
        sleep(1);
        printf( "in main : %d\n" , i );
    }
    return 0;
}
结果:
main will block
in thread : 0
in thread : 1
thread exit
in main : 0
in main : 1
——————/传int参
void *thread(void *arg)
{
	printf("parameter %d\n",*(int*)arg);
    return NULL;
}

int main()
{
    pthread_t pth;
	int test=4;
    pthread_create(&pth, NULL, thread, (void*)&test);
    sleep(1);	
    return 0;
}
结果:parameter 4
——————/共享数据
int test=4;
void *thread(void *arg)
{
	printf("a= %d\n",test++);
    return NULL;
}

int main()
{
    pthread_t pth;
    pthread_create(&pth, NULL, thread, NULL);
    sleep(1);
	printf("a= %d\n",test);
    return 0;
}
结果:a= 4 a= 5
——————/thread_exit.c
void *thread(void *arg)
{
    pthread_exit((void*)1);
	return (void*)2;
}

int main()
{
    pthread_t pth;
	void *ret;
    pthread_create(&pth, NULL, thread, NULL);
	pthread_join(pth,&ret);
	printf("return= %d\n",(int)ret);
    return 0;
}
结果:1
——————/thread_id.c
void *thread(void *arg)
{
	printf("thread id=%ud\n",(unsigned int)pthread_self());
	printf("process id in thread=%d\n",getpid());
	return NULL;
}

int main()
{
    pthread_t pth;
    pthread_create(&pth, NULL, thread, NULL);
	sleep(1);
	printf("process id in main=%d\n",getpid());
    return 0;
}
结果:
thread id=3075590976d
process id in thread=3037
process id in main=3037
——————/thread_clean.c
void *clean(void *arg)
{
    printf("cleanup :%s\n",(char *)arg);
    return NULL;
}

void *thr_fn1(void *arg)
{
    pthread_cleanup_push( (void*)clean,"thread 1 first handler");
    pthread_cleanup_push( (void*)clean,"thread 1 second hadler");
    if(arg)
    {
        return (void *)1;
    }
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);
    return (void *)1;
}

void *thr_fn2(void *arg)
{
    pthread_cleanup_push( (void*)clean,"thread 2 first handler");
    pthread_cleanup_push( (void*)clean,"thread 2 second handler");
	if(arg)
    {
        pthread_exit((void *)2);
    }
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);
    pthread_exit((void *)2);
}

int main(void)
{
    pthread_t tid1,tid2;
    void *tret;
    pthread_create(&tid1,NULL,thr_fn1,(void *)1);
    pthread_create(&tid2,NULL,thr_fn2,(void *)1);
	
	pthread_join(tid1,&tret);
    printf("thread 1 exit code %d  \n",(int)tret);
	
    pthread_join(tid2,&tret);
	printf("thread 2 exit code %d  \n",(int)tret);
	
    return 0;
}
结果:
thread 1 exit code 1
cleanup :thread 2 second handler
cleanup :thread 2 first handler
thread 2 exit code 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值