Linux线程及同步


Linux多线程

 

1.线程概述

线程是一个进程内的基本调度单位,也可以称为轻量级进程。线程是在共享内存空间中并发的多道执行路径,它们共享一个进程的资源,如文件描述和信号处理。因此,大大减少了上下文切换的开销。一个进程可以有多个线程,也就

是有多个线程控制表及堆栈寄存器,但却共享一个用户地址空间。

 

2.线程实现

 

线程创建pthread_create()

  所需头文件#include <pthread.h>

函数原型int pthread_create ((pthread_t *thread, pthread_attr_t *attr,

void *(*start_routine)(void *), void *arg))

thread:线程标识符

attr:线程属性设置

start_routine:线程函数的起始地址

arg:传递给start_routine的参数

函数返回值 成功:0 出错:-1

 

线程退出pthread_exit();

 所需头文件#include <pthread.h>

函数原型void pthread_exit(void *retval)

函数传入值retval:pthread_exit()调用者线程的返回值,可由其他函数如pthread_join 来检索获取

 

等待线程退出并释放资源pthread_join()

  所需头文件#include <pthread.h>

函数原型int pthread_join ((pthread_t th, void **thread_return))

函数传入值

th:等待线程的标识符

thread_return:用户定义的指针,用来存储被等待线程的返回值(不为NULL时)

函数返回值  成功:0  出错:-1

 

代码举例

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.   

5.    /*线程1*/

6.    void thread1()

7.    {

8.        int i=0;

9.        

10.           while(1)

11.           {

12.        printf("thread1:%d\n",i);

13.        if(i>3)

14.           pthread_exit(0);

15.        i++;

16.        sleep(1);

17.       }

18.   }

19.  

20.   /*线程2*/

21.   void thread2()

22.   {

23.       int i=0;

24.       

25.           while(1)

26.           {

27.        printf("thread2:%d\n",i);

28.        if(i>5)

29.           pthread_exit(0);

30.        i++;

31.        sleep(1);

32.       }

33.   }

34.  

35.   int main()

36.   {

37.   pthread_t t1,t2;

38.  

39.   /*创建线程*/

40.   pthread_create(&t1,NULL,(void *)thread1,NULL);

41.   pthread_create(&t2,NULL,(void *)thread2,NULL);

42.   /*等待线程退出*/

43.   pthread_join(t1,NULL);

44.   pthread_join(t2,NULL);

45.   return 0;

46.   }

3同步与互斥

<1>互斥锁

 互斥锁的操作主要包括以下几个步骤。

• 互斥锁初始化:pthread_mutex_init

• 互斥锁上锁:pthread_mutex_lock

• 互斥锁判断上锁:pthread_mutex_trylock

• 互斥锁接锁:pthread_mutex_unlock

• 消除互斥锁:pthread_mutex_destroy

 

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.   

5.    int i=0;/*共享变量*/

6.    pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;/*互斥锁*/

7.   

8.    void thread1()

9.    {

10.       int ret;

11.       while(1)

12.       {

13.           

14.        

15.        ret=pthread_mutex_trylock(&mutex);/*判断上锁*/

16.        

17.        if(ret!=EBUSY)

18.           {

19.           pthread_mutex_lock(&mutex);/*上锁*/

20.           printf("This is thread1:%d\n",i);

21.          i++;

22.         pthread_mutex_unlock(&mutex);/*解锁*/

23.        }

24.        sleep(1);

25.       }

26.   }

27.  

28.   void thread2()

29.   {int ret;

30.       while(1)

31.       {

32.        

33.        ret=pthread_mutex_trylock(&mutex);

34.        if(ret!=EBUSY)

35.           {

36.           pthread_mutex_lock(&mutex);

37.           printf("This is thread2:%d\n",i);

38.          i++;

39.         pthread_mutex_unlock(&mutex);

40.        }

41.        sleep(1);

42.       }

43.   }

44.   int main()

45.   {

46.   pthread_t t1,t2;

47.   pthread_mutex_init(&mutex,NULL);

48.   pthread_create(&t1,NULL,(void *)thread1,NULL);

49.   pthread_create(&t2,NULL,(void *)thread2,NULL);

50.    

51.   pthread_join(t1,NULL);

52.   pthread_join(t2,NULL);

53.    

54.   pthread_mutex_destroy(&mutex);

55.   return 0;

56.   }

<2>信号量

未进行同步处理的两个线程

 

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.   

5.    int i=0;

6.    void thread1()

7.    {

8.        

9.        while(1)

10.       {  

11.           printf("This is thread1:%d\n",i);

12.         i++;

13.         sleep(1);

14.     }

15.   }

16.  

17.  

18.   void thread2()

19.   {

20.  

21.       while(1)

22.       {  

23.           printf("This is thread2:%d\n",i);

24.         i++;

25.         sleep(1);

26.     }

27.   }

28.  

29.   int main()

30.   {

31.   pthread_t t1,t2;

32.  

33.   pthread_create(&t1,NULL,(void *)thread1,NULL);

34.   pthread_create(&t2,NULL,(void *)thread2,NULL);

35.    

36.   pthread_join(t1,NULL);

37.   pthread_join(t2,NULL);

38.    

39.   return 0;

40.   }

执行结果如下:

This is thread1:0

This is thread2:1

This is thread2:2

This is thread1:3

This is thread2:4

This is thread1:4

This is thread2:6

This is thread1:7

......

可以看出:

1.线程2的执行并非必须在线程1之后,如果要求线程2必须在线程1之后执行,称为同步

2.线程1和线程2可能对共享变量i的同时进行读取,如果要求每次只有一个线程读取i,成为互斥

 

信号量的使用

•sem_init用于创建一个信号量,并能初始化它的值。

•sem_wait和sem_trywait相当于P操作,它们都能将信号量的值减一,两者的区别在于若信号量小于零时,   sem_wait将会阻塞进程,而sem_trywait则会立即返回。

•sem_post相当于V操作,它将信号量的值加一同时发出信号唤醒等待的进程。

•sem_getvalue用于得到信号量的值。

•sem_destroy用于删除信号量

 \

 

代码

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.    #include <semaphore.h>

5.   

6.   

7.    int i=0;

8.    sem_t sem1,sem2;

9.   

10.  

11.   void thread1()

12.   {

13.       

14.       while(1)

15.       {  

16.             sem_wait(&sem1);

17.           printf("This is thread1:%d\n",i);

18.         i++;

19.         sleep(3);/*线程1休眠3s,以便观察线程2在输出3s后才会执行*/

20.         sem_post(&sem2);

21.         

22.     }

23.   }

24.  

25.  

26.   void thread2()

27.   {

28.  

29.       while(1)

30.       {  

31.           sem_wait(&sem2);

32.           printf("This is thread2:%d\n",i);

33.         i++;

34.         sem_post(&sem1);

35.         sleep(1);

36.     }

37.   }

38.  

39.   int main()

40.   {

41.   pthread_t t1,t2;

42.  

43.    

44.  

45.   sem_init(&sem1,0,1);/*初始化信号量sem1*/

46.   sem_init(&sem2,0,0);

47.  

48.   pthread_create(&t1,NULL,(void *)thread1,NULL);

49.   pthread_create(&t2,NULL,(void *)thread2,NULL);

50.    

51.   pthread_join(t1,NULL);

52.   pthread_join(t2,NULL);

53.    

54.   return 0;

55.   }

 \

 

 

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.    #include <semaphore.h>

5.   

6.   

7.    int i=0;

8.    sem_t sem;

9.   

10.  

11.   void thread1()

12.   {

13.       

14.       while(1)

15.       {  

16.             sem_wait(&sem);

17.           printf("This is thread1:%d\n",i);

18.         i++;

19.         sleep(3);/*线程1休眠3s,以便观察线程2在输出3s后才会执行*/

20.         sem_post(&sem);

21.         

22.     }

23.   }

24.  

25.  

26.   void thread2()

27.   {

28.  

29.       while(1)

30.       {  

31.           sem_wait(&sem);

32.           printf("This is thread2:%d\n",i);

33.         i++;

34.         sem_post(&sem);

35.         sleep(1);

36.     }

37.   }

38.  

39.   int main()

40.   {

41.   pthread_t t1,t2;

42.  

43.    

44.  

45.   sem_init(&sem,0,1);/*初始化信号量sem*/

46.  

47.   pthread_create(&t1,NULL,(void *)thread1,NULL);

48.   pthread_create(&t2,NULL,(void *)thread2,NULL);

49.    

50.   pthread_join(t1,NULL);

51.   pthread_join(t2,NULL);

52.    

53.   return 0;

54.   }

  

相关内容

    暂无相关文章