Linux 多线程

简介:

线程的优点:

  • 减少系统调度开销,不占有独立的资源,切换速度快,执行效率高。
  • 线程间通信方便,可共享资源。
  • 改善程序设计结构,功能复杂的进程可以分为多个独立的线程分别执行,模块性更强。

   线程分为:用户态线程和核心态线程。

  用户态的多线程程序在运行时不许要特定的内核支持,同一个进程的线程之间进行切换时,不需要调用系统调用。

  核心态线程的实现方法允许不同进程中的的线程按照相同的调度方法进行调度,有利于发挥多处理器的并发优势。

 

线程创建:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*),void *arg);
//thread            指向线程标识符的指针,使用这个标识符来引用新线程
//attr              设置线程属性,设为NULL则生成默认属性的线程
//start_routine     线程运行函数的起始位置
//arg               线程运行函数的参数

线程终止:

复制代码
1.通过线程自身结束

void pthread_exit(void *rval_ptr);
//rval_ptr是函数的返回代码,相当于线程的退出码

2.通过同一进程的其他线程来结束

int pthread_cancel(pthread_t tid);
//tid是要结束线程的标识符
复制代码

下面的函数用于阻塞等待一个线程的结束。

int pthread_join(pthread_t thread, void **return_ptr)

例子:

复制代码
//创建线程,输出当前系统的时间

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<unistd.h>
#include<pthread.h>

void print_currentTime(void)
{
    time_t ct;
    ct=time(NULL);
    //ctime:将秒数转换成字符串
    printf("current time is : '%s'",ctime(&ct));
    pthread_exit("Time thread finished!\n");
}

int main()
{
    int ret;
    void *thread_result;
    pthread_t new_thread;

    ret=pthread_create(&new_thread,NULL,(void*)print_currentTime,NULL);
    if(ret!=0){
        perror("thread creation failed!\n");
        exit(EXIT_FAILURE);
    }

    printf("waiting for new thread....\n");
    ret=pthread_join(new_thread,&thread_result);
    if(ret!=0){
        perror("thread join failed!\n");
        exit(EXIT_FAILURE);
    }

    printf("thread joined, returned: %s\n",(char*)thread_result);
    return 0;
}
//编译时候注意: gcc thread_date.c -o thread_date -lpthread
复制代码

 

线程属性:

线程属性主要包括分离属性,绑定属性,调度属性,堆栈属性,继承属性等,结构为pthread_attr_t。

属性设置函数:

int pthread_attr_init(pthread_attr_t *attr)
//attr是指向属性结构的指针
//注意:此函数必须在调用pthread_creater()函数之前调用

这里提到了一个概念“轻进程(Light Weight Process, LWP)”,位于用户层与系统层之间的内核线程。系统对线程资源的分配以及对线程的控制是通过轻进程来实现的,一个轻进程可以控制一个或多个线程。

获取线程绑定状态函数:

int pthread_attr_getscope(pthread_attr_t *attr, int *scope)
//scope返回绑定属性的状态

设置线程绑定属性函数: 

int pthread_attr_setscope(pthread_attr_t* attr, int scope)
//scope是要绑定的类型

获得线程优先级函数:

int pthread_attr_getschedparam(pthread_attr_t *attr, const struct sched_param *param)
//param中存放线程的调度参数信息

设置线程优先级函数:

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)

获取调度策略函数:

int pthread_attr_getschedpolicy(pthread_attr *attr, int *policy)
//调度策略存放在policy中

设置调度策略函数:

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)

获取并发级别函数:

int pthread_getconcurrency(void)

设置并发级别函数:

int pthread_setconcurrency(int new_level)

 

多线程同步技术:

线程同步机制主要有:互斥量,信号量,条件变量,读写锁等。

互斥量:

数据类型为pthread_mytex_t,主要函数:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_mutex_lock(pthread_mutex_t *mutex);     //阻塞调用
int pthread_mutex_trylock(pthread_mutex_t *mutex);  //非阻塞调用
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//mutex是定义的pthread_mutex_t的指针,mutex_attr是互斥量的属性结构

例子:

复制代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>

pthread_mutex_t mutex;
int count=0;
char msg_buf[64];

void setMsg_Func(void)
{
    while(count>0){
        pthread_mutex_lock(&mutex);
        memset(msg_buf,0,64);
        sprintf(msg_buf,"count=%d.\n",count--);
        pthread_mutex_unlock(&mutex);
        srand((int)time(0));
        sleep(rand()%3);
    }
    pthread_exit(0);
}

void printMsg_Func(void)
{
    while(count>=0){
        pthread_mutex_lock(&mutex);
        printf("%s",msg_buf);
        pthread_mutex_unlock(&mutex);
        if(0==count)
            break;
        srand((int)time(0));
        sleep(rand()%3);
    }
}

int main()
{
    int ret;
    pthread_t set_thread;
    count=4;
    pthread_mutex_init(&mutex,NULL);
    ret=pthread_create(&set_thread,NULL,(void*)&setMsg_Func,NULL);
    if(ret!=0){
        perror("thread creation failed!\n");
        exit(EXIT_FAILURE);
    }
    
    printMsg_Func();
    ret=pthread_join(set_thread,NULL);
    if(ret!=0){
        perror("thread creation failed!\n");
        exit(EXIT_FAILURE);
    }
    printf("Finished!\n");
    pthread_mutex_destroy(&mutex);
    return 0;
}
复制代码

 但是要注意,如果使用互斥量过程中,如果两个线程试图同时占用两个资源,并锁定,可能造成死锁。

条件变量:

  只使用互斥量很可能造成死锁,为此可以加入条件变量。条件变量允许线程阻塞和等待另一个线程发送信号,使用条件变量可以以原子方式阻塞线程,直到满足某个条件为止。

  互斥量主要用来保证对临界区的互斥进入,而条件变量则用于线程的阻塞等待。

复制代码
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);     //创建条件变量
int pthread_cond_signal(pthread_cond_t *cond);                                  //用来释放被阻塞在条件变量cond上的进程
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);            //使线程阻塞
int pthread_cond_broadcast(pthread_cond_t *cond);                               //用来唤醒所有阻塞在条件变量cond上的线程
int pthread_cond_timewait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
//使线程阻塞,与wait不同,它经过abstime时间后,无论条件是否满足,都会释放
int pthread_cond_destroy(pthread_cond_t *cond); //cond是一个指向结构pthread_cond_t的指针 //cond_attr是条件变量的属性结构指针
复制代码

例子:

复制代码
//创建两个线程,偶数时进程1给变量加1,奇数时进程2给变量加1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define MAX_COUNT 9

pthread_mutex_t mutex;
pthread_cond_t cond;
int count=0;

void addCount_odd_Func(void)
{
    pthread_mutex_lock(&mutex);
    while(count<MAX_COUNT){
        if(count%2==1){
            count++;
            printf("addcout_odd_Func():count=%d.\n",count);
            pthread_cond_signal(&cond);
        }
        else
            pthread_cond_wait(&cond,&mutex);
    }
    pthread_mutex_unlock(&mutex);
}

void addCount_even_Func(void)
{
    pthread_mutex_lock(&mutex);
    while(count<MAX_COUNT){
        if(count%2==0){
            count++;
            printf("addCount_even_Func:count=%d.\n",count);
            pthread_cond_signal(&cond);
        }
        else
            pthread_cond_wait(&cond,&mutex);
    }
    pthread_mutex_unlock(&mutex);
}

int main(int argc, char **argv)
{
    int ret;
    pthread_t odd_thread,even_thread;
    pthread_attr_t thread_attr;
    count=0;
    
    pthread_mutex_init(&mutex,NULL);
    pthread_cond_init(&cond,NULL);
    ret=pthread_attr_init(&thread_attr);
    if(ret!=0){
        perror("attribute creation failed!");
        exit(EXIT_FAILURE);
    }
    
    pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED);
    
    ret=pthread_create(&odd_thread,&thread_attr,(void*)&addCount_odd_Func,NULL);
    if(ret!=0){
        perror("thread creation failed!");
        exit(EXIT_FAILURE);
    }
    
    ret=pthread_create(&even_thread,&thread_attr,(void*)&addCount_even_Func,NULL);
    if(ret!=0){
        perror("thread creation failed!");
        exit(EXIT_FAILURE);
    }
    
    while(count<MAX_COUNT);
    
    printf("Finished!");
    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);
    
    return 0;
}
复制代码

 本文转自cococo点点博客园博客,原文链接:http://www.cnblogs.com/coder2012/archive/2013/03/31/2991785.html,如需转载请自行联系原作者

相关文章
|
24天前
|
Linux C++
LInux下Posix的传统线程示例
LInux下Posix的传统线程示例
19 1
|
2月前
|
Java Linux 调度
linux线程池浅谈
linux线程池浅谈
|
1月前
|
算法 Unix Linux
Linux与Qt线程优先级的对应关系:一次全面解析
Linux与Qt线程优先级的对应关系:一次全面解析
23 0
|
2月前
|
Linux 调度 数据库
Linux下的系统编程——线程同步(十三)
Linux下的系统编程——线程同步(十三)
52 0
Linux下的系统编程——线程同步(十三)
|
1月前
|
消息中间件 Linux 调度
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
67 0
|
1月前
|
资源调度 算法 Linux
Linux进程/线程的调度机制介绍:详细解析Linux系统中进程/线程的调度优先级规则
Linux进程/线程的调度机制介绍:详细解析Linux系统中进程/线程的调度优先级规则
91 0
|
1月前
|
存储 安全 数据管理
Linux系统编程教程之Linux线程函数的使用:讲解Linux线程函数
Linux系统编程教程之Linux线程函数的使用:讲解Linux线程函数
19 1
|
1月前
|
缓存 Linux C语言
Linux线程的创建过程
【2月更文挑战第10天】
|
3天前
|
固态存储 Ubuntu Linux
Linux(29) 多线程快速解压缩|删除|监视大型文件
Linux(29) 多线程快速解压缩|删除|监视大型文件
11 1
|
30天前
|
监控 Linux 调度
【Linux 应用开发 】Linux 下应用层线程优先级管理解析
【Linux 应用开发 】Linux 下应用层线程优先级管理解析
48 0