LINUX系统编程之线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LINUX系统编程之线程相关的知识,希望对你有一定的参考价值。

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<stdio.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<semaphore.h>

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;

}


以上是关于LINUX系统编程之线程的主要内容,如果未能解决你的问题,请参考以下文章

Linux系统应用编程 --- 多线程之线程回收

多线程编程之Linux环境下的多线程

Linux系统编程之进程

Liunx C 编程之多线程与Socket

多线程编程之Linux环境下的多线程

多线程编程之Linux环境下的多线程