线程安全和每个线程的存储
1.若函数可供多个线程安全调用,则成为线程安全函数
test@ubuntu:~/share/xinhaoliang$ ./a.out 20 10
produce: 1
produce: 2
produce: 3
produce: 4
produce: 5
produce: 6
produce: 7
produce: 8
produce: 9
produce: 10
produce: 11
produce: 12
produce: 13
produce: 14
produce: 15
produce: 16
produce: 17
produce: 18
produce: 19
produce: 20
buf:yeah
consume: 19
produce: 20
buf:
consume: 19
produce: 20
buf:
consume: 19
produce: 20
buf:
consume: 19
produce: 20
1.若函数可供多个线程安全调用,则成为线程安全函数
2.保障非线程安全函数的手段之一是运用互斥锁来防护对该函数的所有调用。这种方法带来了并发性能的下降,因为同一时点只能有一个线程运行该函数。提升并发性能的另一个方法是:仅在函数中操作共享变量(临界区)的代码前后加入互斥锁。
3.线程共享进程的文件描述符
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define cnt 20
typedef struct tag
{
int arr[cnt+1];
int front;
int tail;
int _fd;
}que;
int is_que_empty(que* q)
{
if((q->front%(cnt+1))==(q->tail%(cnt+1)))
return 1;
return 0;
}
int is_que_full(que* q)
{
if((q->front%(cnt+1))==((q->tail+1)%(cnt+1)))
return 1;
return 0;
}
int que_cnt(que* q)
{
return ((*q).tail-(*q).front+cnt+1)%(cnt+1);
}
pthread_mutex_t mutex ;
pthread_cond_t cond_pro, cond_con ;
que* q;
void* pro_handler(void* arg)
{
pthread_detach(pthread_self());
while(1)
{
pthread_mutex_lock(&mutex);
//printf("produce\n");
while(is_que_full(q))
{
pthread_cond_wait(&cond_pro, &mutex);
}
//que_cnt(q)++;
q->tail=(q->tail+1)%(cnt+1);
printf("produce: %d\n",que_cnt(q));
if(que_cnt(q)==1)
{
pthread_cond_broadcast(&cond_con);
}
pthread_mutex_unlock(&mutex);
sleep(rand()%3+1);
}
}
void* con_handler(void* arg)
{
pthread_detach(pthread_self());
char buf[1024];
if(read(q -> _fd, buf, 1024) == -1)
{
perror("read\n");
exit(1);
}
printf("buf:%s\n", buf);
while(1)
{
pthread_mutex_lock(&mutex);
//printf("consumer\n");
while(is_que_empty(q))
{
pthread_cond_wait(&cond_con, &mutex);
}
//que_cnt(q)--;
q->front=(q->front+1)%(cnt+1);
printf("consume: %d\n",que_cnt(q));
if(que_cnt(q)==19)
{
pthread_cond_broadcast(&cond_pro);
}
pthread_mutex_unlock(&mutex);
sleep(rand()%3+1);
}
}
int main(int argc,char* argv[])
{
int con_cnt , pro_cnt ;
pro_cnt = atoi(argv[1]) ;
con_cnt = atoi(argv[2]) ;
q=(que*)calloc(1,sizeof(que));
srand(getpid());
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond_pro, NULL);
pthread_cond_init(&cond_con, NULL);
pthread_t* arr = (pthread_t*)calloc(con_cnt + pro_cnt, sizeof(pthread_t));
q -> _fd = open("./test.txt", O_RDONLY);
if(q -> _fd == -1)
{
perror("fd error\n");
exit(1);
}
int index = 0 ;
while(pro_cnt > 0)
{
pthread_create(arr + index , NULL, pro_handler, NULL);
index ++ ;
pro_cnt -- ;
}
sleep(5);
while(con_cnt > 0)
{
pthread_create(arr + index , NULL, con_handler, NULL);
index ++ ;
con_cnt -- ;
}
while(1) ;
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond_pro);
pthread_cond_destroy(&cond_con);
close(q -> _fd);
return 0;
}
test@ubuntu:~/share/xinhaoliang$ ./a.out 20 10
produce: 1
produce: 2
produce: 3
produce: 4
produce: 5
produce: 6
produce: 7
produce: 8
produce: 9
produce: 10
produce: 11
produce: 12
produce: 13
produce: 14
produce: 15
produce: 16
produce: 17
produce: 18
produce: 19
produce: 20
buf:yeah
consume: 19
produce: 20
buf:
consume: 19
produce: 20
buf:
consume: 19
produce: 20
buf:
consume: 19
produce: 20
进程描述符传递给线程使用