首页 > 系统 > Linux > 正文

Linux下的线程

2024-06-28 13:27:36
字体:
来源:转载
供稿:网友
linux下的线程一、线程的优点

与传统进程相比,用线程来实现相同的功能有如下优点:

(1)系统资源消耗低。

(2)速度快。

(3)线程间的数据共享比进程间容易的多。

二、多线程编程简单实例
#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <pthread.h>voidthread1_routine(void){    PRintf("new thread:thread_id is %u, process_id is %u/n",         pthread_self(), getpid());}voidthread2_routine(void){    printf("new thread:thread_id is %u, process_id is %u/n",         pthread_self(), getpid());}intmain(void){    pthread_t pt;    printf("old thread:thread_id is %u, process_id is %u/n",        pthread_self(), getpid());     pthread_create(&pt, NULL, (void *)thread1_routine, NULL);    pthread_create(&pt, NULL, (void *)thread2_routine, NULL);    usleep(5);    return(0);}

运行结果如下(可以看出在同一个进程中有三个不同的线程同时在运行):

image

image

三、线程属性

image

线程属性包括绑定属性、分离属性、堆栈地址、堆栈大小和优先级。其中分离属性、堆栈地址以及堆栈大小的介绍可参考http://www.CUOXin.com/nufangrensheng/p/3522583.html。系统默认的是非邦定、非分离、缺省1M的堆栈、与父进程同样级别的优先级。在pthread_create中,把第二个参数设置为NULL的话,将采用默认的属性配置。

1、绑定属性

线程可以分为用户级线程和内核级线程两种(可参考http://blog.csdn.net/songjinshi/article/details/9042265以及http://www.xuebuyuan.com/1380720.html),而绑定属性正是设置用户级线程和内核级线程之间的关系。

绑定属性分为两种:绑定和非绑定。在绑定属性下,一个用户级线程固定分配给一个内核线程,因为CPU时间片的调度是面向内核线程(轻量级进程)的,因此具有 绑定属性的线程可以保证在需要的时候总有一个内核线程与之对应。在非绑定属性下,用户线程和内核线程的关系不是始终固定的,而是由系统根据实际情况分配的。

image

2、优先级

image

image

四、线程互斥

image

image

image

生产者消费者实例(多线程+互斥量):

#include <stdio.h>#include <pthread.h>#include <sched.h>void *producter_f(void *arg);void *consumer_f(void *arg);int buffer_has_item = 0;pthread_mutex_t mutex;int running = 1;int main(void){    pthread_t consumer_t;    pthread_t producter_t;    pthread_mutex_init(&mutex, NULL);    pthread_create(&producter_t, NULL, (void *)producter_f, NULL);    pthread_create(&consumer_t, NULL, (void *)consumer_f, NULL);    sleep(1);      /* 等待线程创建完毕 */    running = 0;    pthread_join(consumer_t, NULL);    pthread_join(producter_t, NULL);    pthread_mutex_destroy(&mutex);    return(0);}void *producter_f(void *arg){    while(running)    {        if(buffer_has_item < 10) /* 最多允许生产10个 */        {            pthread_mutex_lock(&mutex);            buffer_has_item++;            printf("product, total: %d/n", buffer_has_item);            pthread_mutex_unlock(&mutex);        }    }}void *consumer_f(void *arg){    while(running)    {        if(buffer_has_item > 0)   /* 缓冲区为空时不允许再消费 */        {            pthread_mutex_lock(&mutex);            buffer_has_item--;            printf("consume, total: %d/n", buffer_has_item);            pthread_mutex_unlock(&mutex);        }    }}

编译运行结果如下:

image

image

 

五、线程中使用信号量

(此处使用的信号量是POSIX无名信号量:http://www.CUOXin.com/nufangrensheng/p/3564306.html)

线程的信号量与进程的信号量类似,使用线程的信号量可以高效地完成基于线程的资源计数。信号量实际上是一个非负的整数计数器,用来实现对公共资源的控制。在公共资源增加的时候,信号量的值增加;公共资源消耗的时候,信号量的值减少;只有当信号量的值大于0时,才能允许访问信号量所代表的公共资源。

image

image

image

image

image

生产者消费者实例(多线程+信号量):

#include <stdio.h>#include <pthread.h>#include <semaphore.h>void *producter_f(void *arg);void *consumer_f(void *arg);sem_t sem;int running = 1;int main(void){    pthread_t consumer_t;    pthread_t producter_t;        sem_init(&sem, 0, 16);    pthread_create(&producter_t, NULL, (void *)producter_f, NULL);    pthread_create(&consumer_t, NULL, (void *)consumer_f, NULL);    sleep(1);    running = 0;    pthread_join(consumer_t, NULL);    pthread_join(producter_t, NULL);    sem_destroy(&sem);    return(0);}void *producter_f(void *arg){    int semval = 0;    while(running)    {        usleep(1);        sem_post(&sem);        sem_getvalue(&sem, &semval);        printf("product, total: %d/n", semval);    }}void *consumer_f(void *arg){    int semval = 0;    while(running)    {        usleep(1);        sem_wait(&sem);        sem_getvalue(&sem, &semval);        printf("consume, total: %d/n", semval);    }}
编译运行如下:

image

image

image

 

更多关于线程的介绍可参考http://www.CUOXin.com/nufangrensheng/p/3518114.html及其后续博文。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表