Linux 多线程/进程通信同步: 信号量

网友投稿 452 2022-05-29

线程是程序中完成一个独立任务的完整执行序列,即一个可调度的实体。根据运行环境的调度这的身份,线程可分为内核线程和用户线程。内核线程,在有的系统上称为LWP(Light Weight Process,轻量级线程),运行在内核空间,由内核调度;用户线程运行在用户空间,由线程库来调度。当进程的一个内核线程获得CPU的使用权时,它就加载并运行一个用户线程。可见,内核线程相当于用户线程运行的‘容器’,一个进程可以拥有M个内核线程和N个用户线程,其中M<=N,并且一个系统的所有进程中,M和N的比值是固定的。

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

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

线程控制函数

Linux 多线程/进程通信同步: 信号量

线程创建 pthread_create

#include

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

typedef unsigned long int pthread_t;

attr参数用于定制各种不同的线程属性,为NULL时表示默认线程属性。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针的参数arg,如果需要向start_rtn函数传入的参数不止一个,可以把参数放入到一个结构中,然后把这个结构的地址作为arg的参数传入。

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

线程终止 pthread_exit

#include

void pthread_exit(void *rval_ptr);

线程在结束时最好调用该函数,以确保安全、干净的退出。pthread_exit函数通过rval_ptr参数向调用线程的回收者传递退出信息,进程中的其他线程可以调用pthread_join函数访问到这个指针。pthread_exit执行完后不会返回到调用者,而且永远不会失败。

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

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

l  线程可以被同一进程中的其他线程取消

l  线程调用pthread_exit

pthread_join

#include

int pthread_join(pthread_t thread, void **rval_ptr);

返回:成功返回0,出错返回错误代码

thread是目标线程标识符,rval_ptr指向目标线程返回时的退出信息,该函数会一直阻塞,直到被回收的线程结束为止。可能的错误码为:

取消线程 pthread_cancel

#include

int pthread_cancel(pthread_t thread);

返回:成功返回0,出错返回错误代码

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

#include

int pthread_setcancelstate(int state, int *oldstate);

int pthread_setcanceltype(int type, int *oldstate);

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

创建线程简单示例:

#include

#include

#include

#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!\n");

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\n", p);

return 0;

}

linux 任务调度 多线程

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python 并发编程之 Threading 模块
下一篇:C++类的this指针,静态成员,友元函数友元类
相关文章