赞
踩
在操作系统中,线程的实现有以下三种方式:
Linux 实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。 Linux 把所有的线程都当做进程来实现。内核并没有准备特
别的调度算法或是定义特别的数据结构来表征线程。相反,线程仅仅被视为一个与其他进程共享某些资源的进程。每个线程都拥有唯一隶属
于自己的 task_struct,所以在内核中,它看起来就像是一个普通的进程(只是线程和其他一些进程共享某些资源,如地址空间)。
线程库中的接口介绍
#include <pthread.h> /* pthread_create()用于创建线程 thread: 接收创建的线程的 ID attr: 指定线程的属性 start_routine: 指定线程函数 arg: 给线程函数传递的参数 成功返回 0, 失败返回错误码 */ int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); /* pthread_exit()退出线程 retval:指定退出信息 向外界传递的参数 */ int pthread_exit(void *retval); /* pthread_join()等待 thread 指定的线程退出,线程未退出时,该方法阻塞 retval:接收 thread 线程退出时,指定的退出信息 */ int pthread_join(pthread_t thread, void **retval);
线程同步指的是当一个线程在对某个临界资源进行操作时,其他线程都不可以对这个资源进行操作,直到该线程完成操作, 其他线程才
能操作,也就是协同步调,让线程按预定的先后次序进行运行。 线程同步的方法有四种:互斥锁、信号量、条件变量、读写锁。
编写下列程序,将index在五个进程上一起加1000次
#include<stdlib.h> #include<stdio.h> #include<unistd.h> #include<string.h> #include<assert.h> #include<pthread.h> int _index=1; void *thread_fun(void * arg) { for(int i=0; i<1000; i++) { printf("_index=%d\n",_index++); } } int main() { pthread_t id[5]; int i=0; for(;i<5; i++ ) { pthread_create(&id[i],NULL,thread_fun,NULL); } for(i=0; i<5; i++) { pthread_join(id[i],NULL); } exit(0); }
第一次运行:
第二次运行:
第三次运行:
说明线程在对index的加操作上不是完全独立的,如果两个线程同时对index进行加操作,那index的值增加就会少一次,所以每次运行的值都不一样。
对程序添加上信号量,每个线程进行index加操作都要PV操作,这样index值就会固定,线程就同步了
#include<stdlib.h> #include<stdio.h> #include<unistd.h> #include<string.h> #include<assert.h> #include<pthread.h> #include<semaphore.h> sem_t sem; int _index=1; void *thread_fun(void * arg) { for(int i=0; i<1000; i++) { sem_wait(&sem);//P printf("_index=%d\n",_index++); sem_post(&sem);//V } } int main() { sem_init(&sem,0,1); pthread_t id[5]; int i=0; for(;i<5; i++ ) { pthread_create(&id[i],NULL,thread_fun,NULL); } for(i=0; i<5; i++) { pthread_join(id[i],NULL); } exit(0); sem_destroy(&sem); }
运行结果:
互斥锁
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
信号量
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_destroy(sem_t *sem);
条件变量
#include <pthread.h>
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond); //唤醒单个线程
int pthread_cond_broadcast(pthread_cond_t *cond); //唤醒所有等待的线程
int pthread_cond_destroy(pthread_cond_t *cond);
读写锁
#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *rwlock, pthread_rwlockattr_t *attr);
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
多线程程序无论调度顺序怎样,都能得到一个正确的结果,就处于一个线程安全状态
要保证线程安全需要做到:
1) 对线程同步,保证同一时刻只有一个线程访问临界资源。
2) 在多线程中使用线程安全的函数(可重入函数),所谓线程安全的函数指的是:如果一个
函数能被多个线程同时调用且不发生竟态条件,则我们程它是线程安全的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。