赞
踩
线程同步指的是当一个线程在对某个临界资源进行操作时,其他线程都不可以对这个资源进行操作,直到该线程完成操作,其他线程才能操作,也就是协同步调,让线程按预定的先后次序进行运行。线程同步的方法有四种:互斥锁、信号量、条件变量、读写锁。
头文件及函数声明:
#include <pthread.h>
/*
mutex是锁,
attr是锁的属性,一般用不上,传个NULL默认属性就可以
*/
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<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<assert.h> #include<pthread.h> pthread_mutex_t mutex;//定义锁 int g = 0; void* pthread_fun(void* arg) { for(int i = 0; i < 1000; i++) { pthread_mutex_lock(&mutex);//上锁 g++; printf("g = %d\n",g); pthread_mutex_unlock(&mutex);//解锁 } pthread_exit(NULL); } int main() { pthread_mutex_init(&mutex, NULL);//初始化锁 pthread_t id[5]; for(int i = 0; i < 5; i++) { pthread_create(&id[i],NULL,pthread_fun,NULL); } for(int j = 0; j < 5; j++) { char* s = NULL; pthread_join(id[j],(void**)&s); } pthread_mutex_destroy(&mutex);//销毁锁 exit(0); }
运行结果最后输出都是5000,不会再出现低于5000的情况。
头文件及函数声明:
#include <semaphore.h>
/*
sem:信号对象。
pshared:指明信号量的类型。不为0时此信号量在进程间共享,为0时只能为当前进程的所有线程共享。
value:指定信号量值的大小。
*/
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_wait(sem_t *sem);//原子操作,P操作,将信号值减1
int sem_post(sem_t *sem);//原子操作,V操作,将信号值加1
int sem_destroy(sem_t *sem);//销毁信号量
示例代码:函数线程完成将用户输入的数据存储到文件中
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<assert.h> #include<pthread.h> #include<semaphore.h> #include<fcntl.h> sem_t sem1; sem_t sem2; char buff[128] = {0}; void* pthread_fun(void* arg) { int fd = open("sem.txt",O_WRONLY|O_CREAT,0664); assert(fd != -1); while(1) { sem_wait(&sem2); if(strncmp(buff,"end",3) == 0) { break; } write(fd,buff,strlen(buff)); memset(buff,0,128); sem_post(&sem1); } sem_destroy(&sem1); sem_destroy(&sem2); pthread_exit(NULL); } int main() { sem_init(&sem1,0,1); sem_init(&sem2,0,0); pthread_t id; int res = pthread_create(&id,NULL,pthread_fun,NULL); assert(res == 0); while(1) { printf("please input data:\n"); sem_wait(&sem1); fgets(buff,128,stdin); buff[strlen(buff)-1] = '\0'; sem_post(&sem2); if(strncmp(buff, "end", 3) == 0) { break; } } char* s = NULL; pthread_join(id,(void**)s); exit(0); }
条件变量提供了一种线程间的通知机制:当某个共享数据达到某个值的时候,唤醒等待这个共享数据的线程。
头文件及函数声明:
#include <pthread.h>
/*
cond:
attr:
*/
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 <stdio.h> #include <stdlib.h> #include <assert.h> #include <unistd.h> #include <string.h> #include <pthread.h> #include <semaphore.h> pthread_mutex_t mutex; pthread_cond_t cond; void * fun1( void * arg) { char* s = ( char*)arg; while( 1 ) { //阻塞,被唤醒 pthread_mutex_lock(&mutex); pthread_cond_wait(&cond,&mutex); pthread_mutex_unlock(&mutex); printf("fun1 read:%s\n",s); if (strncmp(s,"end",3) == 0 ) { break; } } } void * fun2( void * arg) { char* s = ( char*)arg; while( 1 ) { //阻塞,被唤醒 pthread_mutex_lock(&mutex); pthread_cond_wait(&cond,&mutex); pthread_mutex_unlock(&mutex); printf("fun2 read:%s\n",s); if ( strncmp(s,"end",3) == 0 ) { break; } } } int main() { pthread_t id[2]; char buff[128] = {0}; pthread_cond_init(&cond,NULL); pthread_mutex_init(&mutex,NULL); pthread_create(&id[0],NULL,fun1,( void*)buff); pthread_create(&id[1],NULL,fun2,( void*)buff); while( 1 ) { fgets(buff,128,stdin); if ( strncmp(buff,"end",3) == 0 ) { pthread_mutex_lock(&mutex); pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mutex); break; } else { pthread_mutex_lock(&mutex); pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); } } pthread_join(id[0],NULL); pthread_join(id[1],NULL); exit(0); }
头文件及函数声明:
#include <pthread.h>
/*
rwlock:指向读写锁的指针
attr:读写锁属性,一般传入NULL,使用默认属性
每一个函数执行成功就返回0,否则就返回一个错误码
*/
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);//释放读写锁
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。