linux如何控制线程,linux线程控制

本文深入介绍了Linux环境下使用POSIX线程接口(pthread)进行多线程编程的知识,包括线程与进程的关系、线程的创建与终止、线程私有数据的管理以及线程同步的机制,如互斥锁、条件变量和异步信号。通过实例展示了如何创建和管理线程,并强调了线程同步在多线程编程中的重要性。
摘要由CSDN通过智能技术生成

[摘至linux C编程实战]

线程控制

1.线程与进程的关系

线程是计算机中独立运行的最小单位,运行时占用很少的系统资源。可以把线程看成是操作系统分配CPU时间的基本单元。一个进程可以拥有一个至多个线程。它包含有如下优点:

1)多进程情况下,每个进程有自己独立的地址空间,而在多线程的情况下,同一个进程内的线程共享进程的地址空间。创建一个新的线程耗费的资源要少很多。

2)系统调度方面,线程共享地址空间,因此线程间的切换速度要远远快于进程间的切换速度。

3)同一进程内的线程共享数据时,可以直接提供给其他线程使用,而不必经过操作系统,因此线程间通信更加方便和省时。

线程在进程内部共享地址空间、打开的文件描述符等资源。同时线程也有其私有的数据信息,包括:线程号、寄存器(程序计数器和堆栈指针)、堆栈、信号掩码、优先级、线程私有存储空间。

2.创建线程

linux系统支持POSIX多线程接口,称为pthread。编写linux下的多线程程序,需要包含头文件pthread.h,链接时需要使用库libpthread.a

如果在主线程里面创建线程,程序就会在创建线程的地方产生分支,变成两个部分执行。线程的创建通过函数pthread_create来完成。成功返回0

int pthread_create(pthread_t *thread, pthread_attr_t *attr,

void *(*start_routine)(void *), void *arg);

thread: 参数是一个指针,当线程成功创建时,返回创建线程ID。

attr: 用于指定线程的属性

start_routine: 该参数是一个函数指针,指向线程创建后要调用的函数。

arg: 传递给线程函数的参数。

例子:

1

80f0030aceaa94d3fa42db3f17a27d13.png

#include

<

stdio.h

>

2

80f0030aceaa94d3fa42db3f17a27d13.png#include

<

stdlib.h

>

3

80f0030aceaa94d3fa42db3f17a27d13.png#include

<

unistd.h

>

4

80f0030aceaa94d3fa42db3f17a27d13.png#include

<

pthread.h

>

5

80f0030aceaa94d3fa42db3f17a27d13.png

6

80f0030aceaa94d3fa42db3f17a27d13.png

int

*

thread(

void

*

arg)

7

a8830aa3e473f1afdd8e7f5631fb8b5a.png

bc69a0c18fc82b77df5e30c2b73b2f2d.png

d1d349d5873e80d8dfba590e943d329b.png

{859d62dff7518add086dd78b398b20903.png    pthread_t newthid;959d62dff7518add086dd78b398b20903.png    newthid=pthread_self();1059d62dff7518add086dd78b398b20903.png    printf("this is a new thread, thread ID=%u\n", newthid);1159d62dff7518add086dd78b398b20903.pngreturnNULL;12bbd71a1d05694e22423f4283474dd969.png}

13

80f0030aceaa94d3fa42db3f17a27d13.png

14

80f0030aceaa94d3fa42db3f17a27d13.png

int

main(

void

)

15

a8830aa3e473f1afdd8e7f5631fb8b5a.png

bc69a0c18fc82b77df5e30c2b73b2f2d.png

d1d349d5873e80d8dfba590e943d329b.png

{1659d62dff7518add086dd78b398b20903.png    pthread_t thid;1759d62dff7518add086dd78b398b20903.png    printf("main thread, ID is %u\n", pthread_self());1859d62dff7518add086dd78b398b20903.pngif(pthread_create(&thid, NULL, (void*)thread, NULL)!=0)191a916cca2289cb29e10a5f8a971b9bfd.png

9b1c1f3e99c63a7754d4bf2018dbc98c.pngd1d349d5873e80d8dfba590e943d329b.png{2059d62dff7518add086dd78b398b20903.png        printf("thread creation failed\n");2159d62dff7518add086dd78b398b20903.png        exit(1);220996db8a3804b22aba9046e33c374427.png    }2359d62dff7518add086dd78b398b20903.png    sleep(1);2459d62dff7518add086dd78b398b20903.png    exit(0);25bbd71a1d05694e22423f4283474dd969.png}

3.线程终止

两种方式终止线程。第一通过return从线程函数返回,第二种通过调用pthread_exit()函数使线程退出。需要注意的地方:一是,主线程中如果从main函数返回或是调用了exit函数退出主线程,则整个进程终止,此时所有的其他线程也将终止。另一种是,如果主线程调用pthread_exit函数,则仅仅是主线程消亡,进程不会结束,其他线程也不会结束,知道所有的线程都结束时,进程才结束。

4.线程私有数据

进程内的所有线程共享进程的数据空间,因此全局变量为所有线程所共有。但有时线程也需要保存自己的私有数据,这时可以创建线程私有数据(Thread-specific Date)TSD来解决。在线程内部,私有数据可以被各个函数访问,但对其他线程是屏蔽的。

线程私有数据采用了一键多值的技术,即一个键对应多个数值,访问数据时好像是对同一个变量进行访问,但其实是在访问不同的数据。

创建私有数据的函数有4个:pthread_key_create(创建), pthread_setspecific(设置), pthread_getspecific(获取), pthread_key_delete(删除)。

5.线程同步

线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和异步信号。

1)互斥锁(mutex)通过锁机制实现线程间的同步。同一时刻只允许一个线程执行一个关键部分的代码。

2)条件变量(cond)是利用线程间共享的全局变量进行同步的一种机制。

3)异步信号,如同进程一样,线程也可以通过信号量来实现通信,虽然是轻量级的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值