Linux多线程

多线程就是将一个线程的执行任务划分为多个线程来执行,线程的并发执行可以提高处理器的处理效率。

什么情况下使用多线程?

1. 当需要同时并发执行几项功能,互不干扰。

   例如:网络通信,通信一方应该启动至少两个线程:发送信息和接收信息线程。

   又如:生产者和消费者问题,生产者一边生产,消费者一边消费,而不是等到生产完了再消费。

2. 当有大量的IO时。因为IO时CPU处于空转状态,如果单线程会浪费CPU资源。

    例如:需要读取一个很大的文件,并对其处理,此时可以将文件分为几份,并发处理

    又如:当需要执行大量的sql语句时,可以将sql语句分成几份,并发执行

   

3. 当出现复杂计算时,可将复杂计算和其他不依赖于该计算结果的处理过程并发处理。

请问多线程和多进程如何选择?

Linux操作系统提供了LinuxThreads库,linuxThreads的库函数包含在pthread.h中。

LinuxThread中的主要库函数:

线程的创建和停止:

int pthread_create(pthread_t * pthread,const pthread_attr_t *attr,void *(*start_routine(void*)),void *arg);调用此函数可以创建一个新的线程,新线程创建后执行start_routine 指定的程序。其中参数attr是用户希望创建线程的属性,当为NULL时表示以默认的属性创建线程。arg是向start_routine 传递的参数。当成功创建一个新的线程时,系统会自动为新线程分配一个线程ID号,并通过pthread 返回给调用者。

 void pthread_exit(void *value_ptr);调用该函数可以退出线程,参数value_ptr是一个指向返回状态值的指针。

  

线程控制:

pthread_self(void);为了区分线程,在线程创建时系统为其分配一个唯一的ID号,由pthread_create()返回给调用者,也可以通过pthread_self()获取自己的线程ID。

Int pthread_join (pthread_t thread , void * *status);这个函数的作用是等待一个线程的结束。调用pthread_join()的线程将被挂起直到线程ID为参数thread 指定的线程终止。

join方法测试:

#include <stdio.h>

#include<pthread.h>

void*testjoin(void*arg){

printf("thisisthesubthread,threadidis%u\n",pthread_self());

printf("theargofsubthreadis:%d\n",arg);

sleep(5);

pthread_exit(1);

}

void*main(){

pthread_tthd;

intarg=1000;

if((pthread_create(&thd,NULL,(void*)testjoin,(void*)arg)!=0){

printf("threadcreatefailed!\n");

return;

}

intret;

pthread_join(thd,(void*)&ret);

printf("theexitcodeofsubthreadis%d\n",ret);

printf("thisisthemainthread,threadidis:%u",pthread_self());

}

线程互斥:

      只有拥有互斥量的线程才具有访问资源的权限, 由于互斥对象只有一个,这就决定了任何情况下共享资源(代码或变量)都不会被多个线程同时访问。使用互斥不仅能够在同一应用程序的不同线程中实现资源的安 全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。Linux中通过pthread_mutex_t来定义互斥体机制完成互斥操作。具体的操作函数如下:

pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *attr);初使化一个互斥体变量mutex,参数attr表示按照attr属性创建互斥体变量mutex,如果参数attr为NULL,则以默认的方式创建。

pthread_mutex_lock(pthread_mutex_t *mutex);给一个互斥体变量上锁,如果mutex指定的互斥体已经被锁住,则调用线程将被阻塞直到拥有mutex的线程对mutex解锁为止。

Pthread_mutex_unlock(pthread_mutex_t *mutex);对参数mutex指定的互斥体变量解锁。

线程同步:

       线程同步就是线程等待某个事件发生,当等待的事件发生则继续执行,如果等待的时间没有到达则挂起等待。在Linux中是通过条件变量机制来实现线程同步的。

      Pthread_cond_init(pthread_cond_t *cond,const pthread_cond_t *attr);这个函数按参数attr指定的属性初使化一个条件变量cond。

      Pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);等待一个事件(条件变量)的发生,发出调用的线程自动阻塞,直到相应的条件变量被置1。等待状态的线程不占用CPU时间。

    pthread_cond_signal(pthread_cond_t *cond);解除一个等待参数cond指定的条件变量的线程的阻塞状态。

  

 

生产者和消费者问题:

 

#include <stdio.h>

#include<pthread.h>

#defineBUFFER_SIZE10

intbuffer[BUFFER_SIZE];

pthread_mutex_tmlock;

pthread_cond_tmcond;

intindex=0;

void*producer(void*arg){

while(inti<100){

put(i);

printf("produce%d\n,i);

i++;

}

}

void*consumer(void*arg){

sleep(5);

intret;

while(inti<100){

ret=get();

printf("consume%d\n,ret);

i++;

}

}

voidput(intn){

pthread_mutex_lock(&mlock);

while(index==BUFFER_SIZE){

pthread_cond_wait(&mcond,&mlock);

}

pthread_cond_signal(&mcond);

buffer(index)=n;

index++;

pthread_mutex_unlock(&mlock);

}

intget(){

pthread_mutex_lock(&mlock);

while(index==0){

pthread_cond_wait(&mcond,&mlock);

}

pthread_cond_signal(&mcond);

index--;

intn=buffer(index);

pthread_mutex_unlock(&mlock);

returnn;

}

voidmain(){

pthread_mutex_init(&mlock,NULL);

pthread_cond_init(&mcond,NULL);

pthread_tproth;

pthread_tconth;

pthread_create(&proth,NULL,(void*)put,NULL);

pthread_create(&conth,NULL,(void*)get,NULL);

}

 

 

 

一道google笔试题:

启动4个线程,向4个文件A,B,C,D里写入数据,每个线程只能写一个值。

线程1:只写1

线程2:只写2

线程3:只写3

线程4:只写4

4个文件A,B,C,D。

程序运行起来,4个文件的写入结果如下:

A:12341234。。。。

B:23412341。。。。

C:34123412。。。。

D:41234123。。。。

实现思路:

线程1: for(int i=0;;i++){ fprint((1+i)mod5,"A");}

线程2: for(int i=0;;i++){ fprint((2+i)mod5,"B");}

线程3: for(int i=0;;i++){ fprint((3+i)mod5,"C");}

线程4: for(int i=0;;i++){ fprint((4+i)mod5,"D");}

注意:取模的值为0,则i++ 再取模输入文件

相关推荐