• Linux多线程编程


    Linux多线程编程


            线程是程序中完毕一个独立任务的完整执行序列。即一个可调度的实体。依据执行环境的调度这的身份。线程可分为内核线程和用户线程。内核线程,在有的系统上称为LWP(Light Weight Process,轻量级线程)。执行在内核空间。由内核调度;用户线程执行在用户空间,由线程库来调度。

    当进程的一个内核线程获得CPU的使用权时,它就载入并执行一个用户线程。

    可见,内核线程相当于用户线程执行的‘容器’,一个进程能够拥有M个内核线程和N个用户线程。当中M<=N。而且一个系统的全部进程中。M和N的比值是固定的。

            进程中的不同线程不像不同进程之间那样存在非常大的独立性,全部的线程有全然一样的地址空间,这意味着他们也共享相同的全局变量。除了共享地址空间外,全部的线程还共享同一个打开文件集、子进程以及相关信号等,每一个线程有自己的堆栈。

            在多线程的情况下,进程一般会从当前的单个线程開始,这个线程有能力通过调用一个库函数(如pthread_create)创建新的线程,thread_create函数的參数指定了要执行的函数名。



    线程控制函数

    线程创建 pthread_create

    #include <pthread.h>
    int pthread_create(pthread_t * tidp, const pthread_attr_t *attr, void *(*start_rtn)(void *), void *arg);
    	返回:成功返回0。出错返回错误编号
    
            当pthread_create函数返回成功时。有tidp指向的内存被设置为新创建线程的线程ID,其类型pthread_t定义为

    #include <bits/pthreadtypes.h>
    typedef unsigned long int pthread_t;
    

            attr參数用于定制各种不同的线程属性。为NULL时表示默认线程属性。

    新创建的线程从start_rtn函数的地址開始执行,该函数仅仅有一个无类型指针的參数arg。假设须要向start_rtn函数传入的參数不止一个。能够把參数放入到一个结构中,然后把这个结构的地址作为arg的參数传入。

            线程创建时并不能保证哪个线程会先执行:是新创建的线程还是调用线程。新创建的线程能够訪问调用进程的地址空间。而且继承调用线程的浮点环境和信号屏蔽字,可是该线程的未决信号集被清除。


    线程终止 pthread_exit

    #include <pthread.h>
    void pthread_exit(void *rval_ptr);
    

            线程在结束时最好调用该函数。以确保安全、干净的退出。pthread_exit函数通过rval_ptr參数向调用线程的回收者传递退出信息。进程中的其它线程能够调用pthread_join函数訪问到这个指针。

    pthread_exit运行完后不会返回到调用者,并且永远不会失败。

            线程能够通过下面三种方式退出,在不终止整个进程的情况下停止它的控制流:

    l  线程仅仅是从启动历程中退出,返回值是线程的退出码

    l  线程能够被同一进程中的其它线程取消

    l  线程调用pthread_exit


    pthread_join

    #include <pthread.h>
    int pthread_join(pthread_t thread, void **rval_ptr);
    	返回:成功返回0,出错返回错误代码
    
            thread是目标线程标识符,rval_ptr指向目标线程返回时的退出信息,该函数会一直堵塞。直到被回收的线程结束为止。

    可能的错误码为:


    取消线程 pthread_cancel

    #include <pthread.h>
    int pthread_cancel(pthread_t thread);
    	返回:成功返回0,出错返回错误代码
    

            默认情况下,pthread_cancel函数会使有thread标识的线程的表现为如同调用了參数为PTHREAD_CANCEL的pthread_exit函数,可是,接收到取消请求的目标线程能够决定是否同意被取消以及怎样取消。者分别由一下两个函数来控制

    #include <pthread.h>
    int pthread_setcancelstate(int state, int *oldstate);
    int pthread_setcanceltype(int type, int *oldstate);
    

    注意pthread_cancel并不等待线程结束,它仅仅是提出请求。


    创建线程简单演示样例

    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    #define err_sys(msg) 
    	do { perror(msg); exit(-1); } while(0)
    #define err_exit(msg) 
    	do { fprintf(stderr, msg); exit(-1); } while(0)
    
    void *thread_func(void *arg)
    {
    	printf("hello world!
    ");
    	sleep(1);
    	pthread_exit("hdu");
    }
    
    int main(void)
    {
    	pthread_t tid;
    	char* p = NULL;
    	
    	pthread_create(&tid, NULL, thread_func, NULL);
    
    	pthread_join(tid, (void **)&p);
    
    	printf("message: %s
    ", p);
    
    	return 0;
    }
    

    參考:

            1、《Linux高性能server编程》第14章 多线程编程


  • 相关阅读:
    php打印出10*10表格
    php打印出1到2000年之间所有的闰年
    借鉴一篇好文章
    女程序员的预备篇
    SQL存储过程删除数据库日志文件的方法
    Mongodb无法访问28107的问题
    使用 xsd.exe 命令工具将 xsd 架构生成 类(CS) 文件
    C# 用POST提交json数据
    WinForm 使用 HttpUtility
    Sql Server 分区之后增加新的分区
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6805102.html
Copyright © 2020-2023  润新知