一个进程能够有多少个线程

Linux下的多线程编程需要留意的是先后需要包含头文件pthread.h,在变化可执行文件的时候需要链接库libpthread.a或者libpthread.so。

Linux多线程

线程成立函数:

pthread_create(pthread_t *thread, pthread_attr_t * attr, void
*(*start_routine)(void *),void *arg);

参数表达:

Thread 标示一个线程,它是一个pthread_t类型的变量(unsigned long int)

attr 用于安装线程的习性,默认是null

start_routine当线程分配资源成功后,线程中所运行的单元,通俗的说就是您自己写的一个函数

Arg线程函数运作时传出的一个参数,一般可以用那个流传的参数去控制线程停止

函数再次回到值:

创制成功再次来到0,创制失利再次回到非0值,常见错误重返代码为EAGAIN何EINVAL,EGAIN标示系统中线程的数目达到上限,错误代码EINVAL表示线程的习性非法。

专注:线程成立城成功后,新创造的线程按照参数3和参数4规定一个运转函数,原来的线程在线程创立函数重返后继续运行下一行代码。

 

 

线程停止函数:pthread_join()和pthread_exit()

pthread_join()用来等待一个线程运行截止。这些函数是闭塞函数,从来被等候的线程截至截止,函数才回去并且收回被等候线程的资源。函数的原型为:

Extern int pthread_join_P((pthread_t _th,void
**__thread_return));

_th:线程的标示符,也就是线程成立成功的值,在伊始的说就是pthread_create函数运行成功后的首先个参数

__thread_return:重返值,它是一个指针用来存贮被等候线程的再次回到值。

 

线程函数的终止格局有二种:一种是线程函数运行停止,不用回到结果;另一种就是通过函数pthread_exit()来兑现,将结果传到。

函数原型是:

Extern void pthread_exit_P((void*_retval))

参数是函数的重返值,这些值可以被pthread_join函数捕获,通过__thread_return参数拿到此值。

 

协商线程的创导还有某些务必要提及,这就是线程的特性。一般在我们创立线程的时候设置attr属性的时候都是拔取null,那些是默认参数。不过在众多时候需要调动线程的性质,特别是线程优先级。

线程的属性结构为:pthread_attr_t,在头文件<pthreadtype.h>中定义

typedef struct

{

       int                              detachstate;   线程的告一段落意况

       int                              schedpolicy;  线程调度策略(优先级)

       struct sched_param           schedparam;  线程的调度参数

       int                              inheritsched;  线程的继承性

       int                               scope;       线程的功效域

       size_t                          guardsize;   线程栈末尾的警告缓冲区大小

       int                               stackaddr_set;  运行栈

       void *                         stackaddr;   线程栈的职务

       size_t                          stacksize;    线程栈的轻重缓急

}pthread_attr_t;

要小心的是线程的特性值不可能一向设置,必须要用先关的函数举行操作。线程属性的开头化函数pthread_attr_init(),这么些函数必须在pthread_create()函数从前调用。

 

线程间的排挤:

线程的互斥函数有:互斥函数的起始化pthread_mutex_init(),互斥函数的锁定函数pthread_mutex_lock(),互斥函数的预锁定函数pthread_mutex_trylock(),互斥函数的解锁函数pthread_mutex_unlock(),互斥函数的销毁函数pthread_mutex_destroy()

 

废话不多说,上代码:

#include <stdio.h>

#include <pthread.h>

 #include <unistd.h>

#define MUXNUMBER 10

pthread_mutex_t test_mutex;

int testi = 0;

int testis[10 * 1000];

int count=0;

 

void testfun(void)

{

testis[testi] = testi * 2;

usleep(1000);

testi++;

}

 

void thread_func()

{

    int m_count=0;

   while(m_count<1000)

   {

       pthread_mutex_lock(&test_mutex);

       testfun();

       pthread_mutex_unlock(&test_mutex);

       m_count++;

       //sleep(1);

   }

}

 

int main()

{

    pthread_t t[10];

    pthread_mutex_init(&test_mutex,NULL);

    int i;

    for(i=0;i<MUXNUMBER;i++)

    {

        if(pthread_create(&t[i],NULL,(void*)thread_func,NULL) ==
-1)

        {

            printf(“create  Thread error !\n”);

            exit(1);

        }

        //sleep(1);

    }

 

    for(i=0;i<MUXNUMBER;i++)

    {

         pthread_join(t[i],NULL);

        //sleep(1);

    }

 

    pthread_mutex_destroy(&test_mutex);

    for(i=0;i<10000;i++)

    {

        if(testis[i]!=i*2)

        {

            printf(“第%d个数据出错!:%d\n”,i,testis[i]);

        }

 

    }

    return 0;

}

粗略说下程序效能:程序创立十个线程,每个线程都调用testfun,通过互斥锁保证数据的健康。

代码相比简单,仅仅只是为了让读者强化下边前看的有的概念性的事物。

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

 

代码

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.   }

 图片 2

 

 

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.   }

  

http://www.bkjia.com/Linuxjc/556556.htmlwww.bkjia.comtruehttp://www.bkjia.com/Linuxjc/556556.htmlTechArticleLinux多线程 1.线程概述
线程是一个经过内的为主调度单位,也可以称之为轻量级进程。线程是在共享内存空间中出现的多道执行路径,它们共…

相关文章