重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
LINUX系统编程之线程
创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站建设、成都网站制作、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的洛南网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
情景:
在双核虚拟机中有两个线程函数执行以下功能:
线程一:printf("hello\n");
线程二:printf("world\n");
程序运行时在单核状态下和双核状态下两个线程的执行顺序不一样,请问它们是根据怎样的规则进行调度的?
进程拥有自己的数据段,代码段,堆栈,占用资源多,开销大,通信不方便
为了减少系统开销,从进程中演化出了线程
线程存在于进程中,使用进程的资源
一、概述
线程是CPU调度和分配的基本单位,存在于进程中,是进程中的独立控制流
进程是系统中程序执行和资源分配的基本单位
线程自己不拥有资源
进程默认有一个控制线程(主线程)
线程依赖于进程存在,进程结束线程也结束
线程占用空间少
目的:
多任务程序设计
并发程序设计
网络程序
数据共享
多CPU并行
二、操作
void *fun(void *arg)
注意线程函数参数和返回值类型
pthread_t pth;
创建线程pthread_create(&pth, NULL, fun, (void *)arg);(可用结构体或数组传递多个参数)
等待线程结束回收其资源pthread_join(pth, NULL);
分离线程pthread_detach(pth);
退出线程pthread_exit();
取消线程pthread_cancle();
取消状态pthread_setcancelstate();
取消类型pthread_setcanceltype();
设置取消点pthread_testcancel();
清理pthread_cleanup_push();pthread_cleanup_pop();两个函数必须成对存在
编译gcc a.c 加-lpthread
gtk编程中多个线程可能使用同一资源照成界面冻结,所以要线程互斥
可使用gtk_threads_enter();和gtk_threads_leave();实现
三、线程的同步和互斥
互斥:多个任务访问同一公共资源,同一时刻只有一个任务可以访问
互斥锁和信号量
1.互斥锁:mutex,上锁解锁两种状态,解锁必须由上锁者完成
申请mutex,如果lock则阻塞申请者
pthread_mutex_t mutex;
pthread_mutex_lock(&mutex);
pthread_mutex_trylock(&mutex);
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
2.信号量
非负的整数计数器
对信号量进行减操作,如果为0则阻塞
PV原语,P减,V加
sem_t sem;
sem_init(&sem, 0, 1);
sem_wait(&sem);sem_trywait(&sem);
sem_post(&sem);
int val;
sem_getvalue(&sem, &val);
sem_destroy(&sem);
通过信号量同步操作实现多任务之间按照顺序运行
线程:无名信号量,进程:有名信号量
一个任务一个信号量
有名信号量
sem_t *sem_open("sem", O_RDWR);
sem_close(sem);
sem_unlink("sem");
有名信号量的名字在程序中和文件系统中不一样
有名信号量会保存之前的值所以使用前应该先删除再创建
实例:
有一个仓库生产者负责生产产品,并放入仓库,消费者从仓库拿走产品
要求仓
库每次只能入一人
仓库中最多存放10个产品,仓库满时不能再放入产品
仓库空时不能再从中取出产品
生产消费速度不同
思路:
生产和消费各一个线程,仓库为互斥,假设容量为10,库存为3
假设生产速度比消费速度快
信号量的值等于剩余产品
#include
#include
#include
#include
int total=10;//总量
int last=7;//剩余量
sem_t sem_p;
sem_t sem_c;
void *produce(void *arg)
{
//sem_t *temp_semp=(sem_t *)arg;
while(1)
{
// sem_p=total-last;
if(9 >= last)
{
sleep(2);
sem_wait(&sem_p);
last++;
printf("in!last=%d\n",last);
sem_post(&sem_c);
}
}
}
void *cost(void *arg)
{
//sem_t *temp_semp=(sem_t *)arg;
while(1)
{
// sem_c=last;
if(1 <= last)
{
sem_wait(&sem_c);
last--;
printf("out!last=%d\n",last);
sem_post(&sem_p);
sleep(3);
}
}
}
int main()
{
pthread_t pth_p,pth_c;
sem_init(&sem_p,0,total-last);
sem_init(&sem_c,0,last);
printf("init_last=%d\n",last);
pthread_create(&pth_p,NULL,produce,NULL);
pthread_create(&pth_c,NULL,cost,NULL);
while(1);
return 0;
}