浅谈Linux多线程编程和Windows多线程编程的异同

对于linux操作系统,互斥也是类似的,只是函数不同罢了。在linux下,和互斥相关的几个函数也要闪亮登场了。

               pthread_mutex_init函数:初始化一个互斥锁;

               pthread_mutex_destroy函数:注销一个互斥锁;

               pthread_mutex_lock函数:加锁,如果不成功,阻塞等待;

               pthread_mutex_unlock函数:解锁;

                pthread_mutex_trylock函数:测试加锁,如果不成功就立即返回,错误码为EBUSY;

    至于这些函数的用法,google上一搜,就出来了,呵呵,在这里不多讲了。windows下还有一个可以用来保护数据的方法,也是线程同步的方式

就是临界区了。临界区和互斥类似。它们之间的区别是,临界区速度快,但是它只能用来同步同一个进程内的多个线程。临界区的获取和释放函数如下:

EnterCriticalSection() 进入临界区; LeaveCriticalSection()离开临界区。 对于多线程共享内存的东东就讲到这里了。

 

  (2)采用消息机制进行多线程通信和同步,windows下面的的消息机制的函数用的多的就是postmessage了。Linux下的消息机制,我用的较少,就不在这里说了,如果谁熟悉的,也告诉我,呵呵。

 

(3)windows下的另外一种线程通信方法就是事件和信号量了。同样针对我开始举得例子,2个线程同步,他们之间传递信息,可以采用事件(Event)或信号量(Semaphore),比如第一个线程完成生产的数据后,就必须告诉第2个线程,他已经把数据准备好了,你可以来取走了。第2个线程就把数据取走。呵呵,这里可以采用消息机制,当第一个线程准备好数据后,就直接postmessage给第2个线程,按理说采用postmessage一个线程就可以搞定这个问题了。呵呵,不是重点,省略不讲了。

对于linux,也有类似的方法,就是条件变量了,呵呵,这里windows和linux就有不同了。要特别讲讲才行。

对于windows,采用事件和信号量同步时候,都会使用waitforsingleobject进行等待的,这个函数的第一个参数是一个句柄,在这里可以是Event句柄,或Semaphore句柄,第2个参数就是等待的延迟,最终等多久,单位是ms,如果这个参数为INFINITE,那么就是无限等待了。释放信号量的函数为ReleaseSemaphore();释放事件的函数为SetEvent。当然使用这些东西都要初始化的。这里就不讲了。Msdn一搜,神马都出来了,呵呵。神马都是浮云!

对于linux操作系统,是采用条件变量来实现类似的功能的。Linux的条件变量一般都是和互斥锁一起使用的,主要的函数有:

pthread_mutex_lock ,

pthread_mutex_unlock,

pthread_cond_init

pthread_cond_signal

pthread_cond_wait

pthread_cond_timewait

为了和windows操作系统进行对比,我用以下表格进行比较:

      

对象

操作

Linux

Windows

线程

创建

Pthread_create

CreateThread/Afxbeginthread

退出

Pthread_exit

ThreadExit

等待

Pthread_join

WaitForSingleObject

互斥锁

创建

Pthread_mutex_init

CreateMutex

销毁

Pthread_mutex_destroy

CloseHandle

加锁

Pthread_mutex_lock

WaitForSingleObject

解锁

Pthread_mutex_unlock

ReleaseMutex

条件变量

创建

pthread_cond_init

CreateEvent

销毁

Pthread_cond_destroy

CloseHandle

触发

pthread_cond_signal

SetEvent

广播

Pthread_cond_broadcast

SetEvent/ResetEvent

等待

Pthread_cond_wait

SingleObjectAndWait

Pthread_cond_timedwait

 

 

 

 

Linux专有的

Pthread_cleanup_push:

Pthread_cleanup_pop:

这两个函数用来保护当程序出现异常时,清除资源等。

Windows专有

Semaphore

 

对照以上表格,总结如下:

(1) Pthread_cleanup_push,Pthread_cleanup_pop:

这一对函数push和pop的作用是当出现异常退出时,做一些清除操作,即当在push和pop函数之间异常退出,包括调用pthread_exit退出,都会执行push里面的清除函数,如果有多个push,注意是是栈,先执行后面的那个函数,在执行前面的函数,但是注意当在这2个函数之间通过return 退出的话,执不执行push后的函数就看pop函数中的参数是不是为0了。还有当没有异常退出时,等同于在这里面return退出的情况,即:当pop函数参数不为0时,执行清除操作,当pop函数参数为0时,不执行push函数中的清除函数。

(2)linux的pthread_cond_signal和SetEvent的不同点

Pthread_cond_singal释放信号后,当没有Pthread_cond_wait,信号马上复位了,这点和SetEvent不同,SetEvent是不会复位的。详解如下:

条件变量的置位和复位有2种常用模型:第一种模型是当条件变量置位时(signaled)以后,如果当前没有线程在等待,其状态会保持为置位(signaled),直到有等待的线程进入被触发,其状态才会变为unsignaled,这种模型以采用Windows平台上的Auto-set Event 为代表。

第2种模型则是Linux平台的pthread所采用的模型,当条件变量置位(signaled)以后,即使当前没有任何线程在等待,其状态也会恢复为复位(unsignaled)状态。

条件变量在Linux平台上的这种模型很难说好坏,在实际应用中,我们可以对

代码稍加改进就可以避免这种差异的发生。由于这种差异只会发生在触发没有被线程等待在条件变量的时刻,因此我们只需要掌握好触发的时机即可。最简单的做法是增加一个计数器记录等待线程的个数,在决定触发条件变量前检查该变量即可。

示例  使用 pthread_cond_wait()  pthread_cond_signal()

 

pthread_mutex_t count_lock;

pthread_cond_t count_nonzero;

unsigned count;

decrement_count()

{

    pthread_mutex_lock(&count_lock);

    while (count == 0)

        pthread_cond_wait(&count_nonzero, &count_lock);

    count = count - 1;

    pthread_mutex_unlock(&count_lock);

}

 

increment_count()

{

    pthread_mutex_lock(&count_lock);

    if (count == 0)

        pthread_cond_signal(&count_nonzero);

    count = count + 1;

    pthread_mutex_unlock(&count_lock);

 

}

 

(3) 注意Pthread_cond_wait条件返回时互斥锁的解锁问题

extern int pthread_cond_wait __P ((pthread_cond_t *__cond,pthread_mutex_t *__mutex));

 调用这个函数时,线程解开mutex指向的锁并被条件变量cond阻塞。线程可以被函数pthread_cond_signal和函数 pthread_cond_broadcast唤醒线程被唤醒后,它将重新检查判断条件是否满足,如果还不满足,一般说来线程应该仍阻塞在这里,被等待被下一次唤醒。如果在多线程中采用pthread_cond_wait来等待时,会首先释放互斥锁,当等待的信号到来时,再次获得互斥锁,因此在之后要注意手动解锁。举例如下:

 

#include <pthread.h>

#include <stdio.h>

#include <stdlib.h>

 

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /*初始化互斥锁*/

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;  //初始化条件变量

 

void *thread1(void *);

void *thread2(void *);

 

int i=1;

int main(void)

{

        pthread_t t_a;

        pthread_t t_b;

        pthread_create(&t_a,NULL,thread1,(void *)NULL);/*创建进程t_a*/

        pthread_create(&t_b,NULL,thread2,(void *)NULL); /*创建进程t_b*/

        pthread_join(t_b, NULL);/*等待进程t_b结束*/

        pthread_mutex_destroy(&mutex);

        pthread_cond_destroy(&cond);

         exit(0);

}

 

void *thread1(void *junk)

{

        for(i=1;i<=9;i++)

        {

             printf("IN one\n"); 

             pthread_mutex_lock(&mutex);//

           if(i%3==0)

              pthread_cond_signal(&cond);/*,发送信号,通知t_b进程*/

           else      

                  printf("thead1:%d\n",i);

              pthread_mutex_unlock(&mutex);//*解锁互斥量*/

              printf("Up  Mutex\n");     

       sleep(3);

        }

 

}

 

void *thread2(void *junk)

{

        while(i<9)

        {

             printf("IN two \n"); 

              pthread_mutex_lock(&mutex);

            if(i%3!=0)

                   pthread_cond_wait(&cond,&mutex);/*等待*/

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

            pthread_mutex_unlock(&mutex);

            printf("Down  Mutex\n");

 

            sleep(3);

 }

 

}

 

输出如下:

IN one

thead1:1

Up  Mutex

IN two

IN one

thead1:2

Up  Mutex

IN one

thread2:3

Down  Mutex

Up  Mutex

IN one

thead1:4

Up  Mutex

IN two

IN one

thead1:5

Up  Mutex

IN one

Up  Mutex

thread2:6

Down  Mutex

IN two

thread2:6

Down  Mutex

IN one

thead1:7

Up  Mutex

IN one

thead1:8

Up  Mutex

IN two

IN one

Up  Mutex

thread2:9

Down  Mutex

 

注意蓝色的地方,有2个thread2:6,其实当这个程序多执行几次,i=3和i=6时有可能多打印几个,这里就是竞争锁造成的了。

引自:http://www.linuxidc.com/Linux/2011-03/33603p2.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux 多线程编程是一种技术,可以让一个程序并行地处理多个任务。它可以提高程序的执行效率,更有效地使用计算机的资源,并减少系统响应时间。Linux 是一种流行的操作系统,支持多线程编程多线程编程是指在同一进程中同时执行多个线程,每个线程执行自己的任务。下面是一些关于 Linux 多线程编程的基本概念和技术: 1. 线程和进程的区别:线程是进程内的一个执行单元,进程是操作系统分配资源的一个独立单位。 2. 线程同步:线程同步是指协调多个线程之间的执行顺序,防止出现数据竞争和死锁等问题。常见的线程同步技术包括互斥量、条件变量和信号量等。 3. 线程池:线程池是一种预先创建一组线程并重复使用的技术。线程池可以提高多线程程序的效率和性能。 4. POSIX 线程库:POSIX 线程库是 Linux 操作系统支持的一种多线程编程接口,提供了一套标准的多线程 API,包括创建、销毁、同步和调度线程等功能。 5. 多线程调试:多线程程序的调试需要注意避免数据竞争和死锁等问题,可以使用调试工具和技术,如 gdb 和 Valgrind 等。 总之,多线程编程Linux 程序员必备的技能之一,掌握多线程编程技术可以提高程序的效率和性能,同时也需要注意避免常见的线程问题。 ### 回答2: Linux 多线程编程是一种在 Linux 操作系统上开发并行应用程序的方式,它允许一个程序同时执行多个线程,从而提高程序的响应速度和运行效率。在 Linux 中,线程是轻量级的进程,它们共享同一进程的资源和数据,可以同时运行在不同的 CPU 核心上,使得程序在多核系统中具有更好的性能表现。 Linux 提供了多种多线程编程的 API,其中最常用的是 pthreads 库,它是一组 C 语言函数,可用于创建、同步和管理多个线程。使用 pthreads 库编写多线程程序的基本步骤包括定义线程函数、创建线程、执行线程、同步线程和销毁线程,这些步骤需要程序员显式地调用相关的 API 函数来实现。 在编写多线程程序时,必须考虑线程之间的共享资源和同步问题。共享资源包括程序的数据、文件、网络连接等,可以使用临界区、互斥锁、信号量等技术来保护。同步问题则是确保多个线程之间按照正确的顺序执行,不会产生死锁、饥饿等问题,可以使用信号量、互斥锁、条件变量等技术来实现。 此外,多线程编程还需要考虑到线程的调度问题,即如何让不同的线程在不同的时间片内执行,从而实现线程的抢占和优先级控制。Linux 提供了优先级调度器和时间片分配器来实现线程的调度,程序员可以根据需要设定优先级和时间片长度来控制线程的执行顺序和时间切片。 总之,Linux 多线程编程是一种高效、灵活和可扩展的编程模型,能够充分利用多核系统的性能,并实现程序的并行化和异步化。开发者需要熟悉多线程编程的基本概念、API 和技术,遵循正确的资源共享和同步策略,才能编写出高质量、可靠、并发的多线程程序。 ### 回答3: Linux 多线程编程是指在 Linux 操作系统下使用多个线程同时运行程序来提高程序的运行效率、并实现多任务处理。多线程编程具有使用方便、管理灵活、响应速度相对于进程更快的优势,常被应用于高并发服务器中。 在 Linux 中,多线程编程的实现主要依赖于 pthread 库。该库提供了一些线程函数和数据结构,用于创建、控制、同步和分离线程等操作。以下是一些常用的 pthread 函数: 1. pthread_create():用于创建一个新线程; 2. pthread_join():主线程阻塞等待子线程结束; 3. pthread_exit():用于在线程代码中退出线程; 4. pthread_mutex_lock():线程加锁; 5. pthread_mutex_unlock():线程解锁; 6. pthread_cond_wait():线程等待; 7. pthread_cond_signal():唤醒等待的线程。 除了 pthread 库,Linux 还提供了其它一些可用于多线程编程的工具和技术,如: 1. OpenMP:一种基于共享内存的多线程编程模型; 2. MPI:一种消息传递的分布式并行编程模型。 当进行多线程编程时,需要注意以下几个方面: 1. 多线程编程的并发性可能会导致一些竞态条件,需要使用锁或互斥量进行同步; 2. 在实现多线程编程过程中,应该尽量避免使用全局变量或静态变量; 3. 在多线程编程实践中,应注意资源的释放和内存泄漏的问题。 总之,Linux 多线程编程是一项非常重要的技能,它能够在提高程序性能和响应速度方面发挥重要作用。熟练掌握多线程编程技术,对于编写高效稳定的服务端程序和优化多线程应用程序的性能都非常有益。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值