精华内容
下载资源
问答
  • 进程(process)和线程(thread)是操作系统的基本概念,但是...vs 线程 :一个进程可以包含多个线程" title="进程 vs 线程 :一个进程可以包含多个线程" style="border:0px; max-width:602px; height:auto; ma

    进程(process)和线程(thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握。

    最近,我读到一篇材料,发现有一个很好的类比,可以把它们解释地清晰易懂。

    1.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。

    2.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。

    3.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。

    4.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    一个车间里,可以有很多工人。他们协同完成一个任务。

    5.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    线程就好比车间里的工人。一个进程可以包括多个线程。

    6.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。

    7.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。

    8.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。

    9.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。

    10.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做"信号量"(Semaphore),用来保证多个线程不会互相冲突。

    不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。

    11.

    进程 <wbr>vs <wbr>线程 <wbr>:一个进程可以包含多个线程

    操作系统的设计,因此可以归结为三点:

    (1)以多进程形式,允许多个任务同时运行;

    (2)以多线程形式,允许单个任务分成不同的部分运行;

    (3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。

    (完)

    展开全文
  • 既然如此,我们可以想象,一个系统中的进程数量肯定是有上限的,不然系统资源就会不够用了,同样的道理,一个进程中的线程资源也是有上限的。 Linux中最多可以有多少个进程? 一.Linux中有一个命令可以帮助...

    说明

    进程:系统分配资源的载体,是程序运行的实例;

    线程:程序执行的最小单元,是进程中的一个实体用来执行程序,一个进程中有多个线程。

     

    既然如此,我们可以想象,一个系统中的进程数量肯定是有上限的,不然系统资源就会不够用了,同样的道理,一个进程中的线程资源也是有上限的。

     

     

    Linux中最多可以有多少个进程?

    一.Linux中有一个命令可以帮助我们查看系统中的进程上限

    [pigff@izbp13yd4r85qvk53t04mbz ~]$ ulimit -u
    4096


    这属于软限制,是可以改变的。也就是说在我的机器上最多可以有4096个进程,但是我可以通过改变这个参数的值来修改对于进程数量的软限制,比如说用下面的命令将软限制改到5120。


     ulimit -u 5120


     二.我们用pid_t来表示一个进程的pid,因此能表示的进程的范围一定不会超过pid_t类型的大小


    [pigff@izbp13yd4r85qvk53t04mbz ~]$ cat /proc/sys/kernel/pid_max
    32768


    pid_t实际上就是一个short类型变量,当然这里能表示的范围只是进程id最多表示到这么多,这只是一个理论值,实际上,由于内存等系统资源的限制,根本不会同时有这么多的进程存在。

     

    一个进程中最多可以有多少个线程?

     

    一、ulimit -n可以查看一个进程最多可以打开多少文件描述符数;

     

    Linux中线程占用内存中,取决于分配给线程的调用栈大小,可以用ulimit -s命令来查看大小(stack size (kbytes,-s)表示线程堆栈大小,一般常见的有10M或者是8M)。我们还知道,一个进程的虚拟内存是4G,在Linux32位平台下,内核分走了1G,留给用户用的只有3G,于是我们可以想到,创建一个线程占有了10M内存,总共有3G内存可以使用。于是可想而知,3G/10M=最大线程数,最多可以创建差不多300个左右的线程。 但实际会比这个数小一点,因为程序本身占内存,还有些管理线程。64位系统的不一样,64系统的线程数并不是简单是用 内存/线程栈 ,

    因此,进程最多可以创建的线程数是根据分配给调用栈的大小,以及操作系统(32位和64位不同)共同决定的。
     

     

     

     

     

     

     

      可以使用ulimit -s来设置stack size,设置的小一点开辟的线程就多。
        同时,

      /usr/include/bits/local_lim.h中的PTHREAD_THREADS_MAX限制了进程的最大线程数
      /proc/sys/kernel/threads-max中限制了系统的最大线程数

       查看公司的服务器:

       限制数为:  2^19
       实际测试结果:2^16

    三、最靠谱的方法还是自己写程序测试的结果

    #include<unistd.h>
    #include<stdlib.h>
    #include<pthread.h>
    #include<stdio.h>
     
    void* foo(void* param)
    {
    }
     
    int main()
    {
            int i = 0;
            pthread_t thread;
            while (1) {
                    if (pthread_create(&thread, NULL, foo, NULL) != 0)
                            break;
                    i ++;
            }
            printf("i = %d\n", i);
    }

    编译命令如下:

    g++ main.cpp -o main -lpthread

     执行结果:

    [root@localhost]# ./main

    i = 32747

    原文:

    https://blog.csdn.net/lvyibin890/article/details/82255047

    https://www.cnblogs.com/bugutian/p/9722240.html

    展开全文
  • 进程

    万次阅读 2021-05-25 14:29:00
    个进程不能共享全局变量7.启动多个子进程8.多进程文件拷贝9.封装进程对象10.进程间的通信 进程 .什么是多任务 现代的操作系统(Windows,Mac OS X,Linux,UNIX等)都支持“多任务”。 什么叫做多

    进程

    一.什么是多任务

    现代的操作系统(Windows,Mac OS X,Linux,UNIX等)都支持“多任务”。
    什么叫做多任务:操作系统同时运行多个任务

    • 单核CPU实现多任务原理:操作系统轮流让各个任务交替执行,QQ执行2us,切换到微信,再执行2us,再切换到陌陌,执行2us······。表面上是每个任务反复执行下去,但是CPU调度执行速度太快了,导致我们感觉就像所有任务都在同时执行一样。

    • 多核CPU实现多任务原理:真正的并行执行多任务只能在多核CPU上实现,但是由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动把很多任务轮流调度到每个核心上执行。

    并发:看上去一起执行,任务数多于CPU核心数
    并行:真正一起执行,任务数小于等于CPU核心数

    二、实现多任务的方式:

    1.多进程模式(使用较多)
    2.多线程模式(使用最多)
    3.协程模式 (使用较少)
    4.多进程+多线程模式 (容易出错)

    生活中与很多场景是同时进行的,比如开车的时候手和脚是同时来控制车。还有一些歌手边唱歌边跳舞。
    我们可以理解为我们的大脑控制着我们的身体进行不同的动作。大脑就是cpu,身体的所有支配动作用到的部位为我们的资源。
    试想下如果我们的大脑只能控制一个动作完成后才能控制下一个动作,也就是说我们只能先唱完歌再去跳舞,这是不是很尴尬呢?

    示例1 一般情况下执行唱歌、跳舞

    from time import sleep 
    def sing():
        for i in range(3):
            print('我正在唱歌。。。%d'%i)
            sleep(1)
    
    def dance():
        for i in range(3):
            print('我正在跳舞。。。%d'%i)
            sleep(1)
    if __name__ == '__main__':
        sing() # 先唱歌
        dance() # 再跳舞
    '''
    我正在唱歌。。。0
    我正在唱歌。。。1
    我正在唱歌。。。2
    我正在跳舞。。。0
    我正在跳舞。。。1
    我正在跳舞。。。2'''
    
    

    示例2 单线程执行函数

    from time import sleep
    # 单线程执行
    def saySorry():
        print("亲爱的,圣诞节快乐!")
        sleep(1)
    
    if __name__ == "__main__":
        for i in range(5):
            saySorry()
    """
    # 亲爱的,圣诞节快乐!
    # 亲爱的,圣诞节快乐!
    # 亲爱的,圣诞节快乐!
    # 亲爱的,圣诞节快乐!
    # 亲爱的,圣诞节快乐!
    """
    
    

    示例3 多线程执行函数

    import threading
    from time import sleep
    # 多线程执行
    def saySorry():
        print("亲爱的,圣诞节快乐!")
        sleep(1)
    
    if __name__ == "__main__":
        for i in range(5):
            t = threading.Thread(target=saySorry)
            t.start()  # 启动线程,即让线程开始执行
    """
    # 亲爱的,圣诞节快乐!
    # 亲爱的,圣诞节快乐!
    # 亲爱的,圣诞节快乐!
    # 亲爱的,圣诞节快乐!
    # 亲爱的,圣诞节快乐!
    """
    
    

    示例4多线程执行唱歌、跳舞1

    import threading
    from time import sleep,ctime
    # 多线程执行唱歌跳舞的多任务。
    def sing():
        for i in range(3):
            print("正在唱歌...%d"%i)
            sleep(1)
    
    def dance():
        for i in range(3):
            print("正在跳舞...%d"%i)
            sleep(1)
    
    if __name__ == '__main__':
        print('---开始---:%s'%ctime())
    
        t1 = threading.Thread(target=sing)
        t2 = threading.Thread(target=dance)
    
        t1.start()
        t2.start()
    
        sleep(5)  # 屏蔽此行代码,试试看,程序是否会立马结束?
        print('---结束---:%s'%ctime())
    
    '''
    ---开始---:Tue May 25 11:26:19 2021
    正在唱歌...0
    正在跳舞...0
    正在唱歌...1
    正在跳舞...1
    正在唱歌...2
    正在跳舞...2
    ---结束---:Tue May 25 11:26:24 2021
    '''
    
    

    示例5多线程执行唱歌、跳舞2

    import threading
    from time import sleep,ctime
    # 多线程执行唱歌跳舞的多任务。
    def sing():
        for i in range(3):
            print("正在唱歌...%d"%i)
            sleep(1)
    
    def dance():
        for i in range(3):
            print("正在跳舞...%d"%i)
            sleep(1)
    
    if __name__ == '__main__':
        print('---开始---:%s'%ctime())
    
        t1 = threading.Thread(target=sing)
        t2 = threading.Thread(target=dance)
    
        t1.start()
        t2.start()
    
        # sleep(5) # 屏蔽此行代码,试试看,程序是否会立马结束?
        print('---结束---:%s'%ctime())
    
    '''---开始---:Tue May 25 11:19:25 2021
    正在唱歌...0
    正在跳舞...0---结束---:Tue May 25 11:19:25 2021
    
    正在唱歌...1
    正在跳舞...1
    正在唱歌...2
    正在跳舞...2'''
    
    

    三、什么是进程

    1.什么是进程?

    对于操作系统而言,一个任务就是一个进程,一个应用就是一个进程。
    程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念,而进程是程序在处理机上的一次执行过程,它是一个动态的概念。
    进程是系统中程序执行和资源分配的基本单位,每个进程都有自己的数据段、代码段、和堆栈段。
    进程是一个具有一定独立功能的程序,一个实体,每一个进程都有它自己的地址空间。

    2.进程的状态

    进程执行时的间断性,决定了进程可能具有多种状态,事实上,运行中的进程具有以下三种基本状态。
    (1)就绪状态(Ready)
    (2)运行状态(Running)
    (3)阻塞状态(Blocked)

    3.单任务现象

    # 单任务现象
    from time import sleep
    
    def run():
        while True:
            print("haiyan is my wife")
            sleep(2)
    
    if __name__ == "__main__":
        while True:
            print("yangyu is a good man")
            sleep(1)
    
        run()    # 执行不了.因为上面的循环没有结束。
    '''
    执行结果:不停打印
    yangyu is a good man
    yangyu is a good man
    yangyu is a good man
    yangyu is a good man
    yangyu is a good man
    yangyu is a good man
    yangyu is a good man
    yangyu is a good man
    ...
    '''
    
    

    4.启动进程实现多任务

    # 启动进程实现多任务
    """
    multiprocessing 库
    跨平台版本的多进程模块,提供了一个Process类来代表一个进程对象
    """
    from multiprocessing import Process
    import os
    from time import sleep
    
    
    # 子进程需要执行的代码
    def run(str1):
        while True:
            # os.getpid()获取当前进程的id号
            # os.getppid()获取当前父进程的id号
            print("yangyu is a %s man--%s--%s" % (str1, os.getpid(), os.getppid()))
            sleep(1.2)
    
    
    if __name__ == "__main__":
        print("主(父)进程启动-%s" % (os.getpid()))
        # 创建子进程
        # target说明进程执行的任务
        p = Process(target=run, args=("nice",))
        # 启动进程
        p.start()
    
        while True:
            print("yangyu is a good man")
            sleep(1)
    '''
    主(父)进程启动-2372
    yangyu is a good man
    yangyu is a good man
    yangyu is a nice man--5664--2372
    yangyu is a good man
    yangyu is a good man
    yangyu is a nice man--5664--2372
    yangyu is a good man
    yangyu is a nice man--5664--2372
    yangyu is a good man
    yangyu is a nice man--5664--2372
    yangyu is a good man
    yangyu is a nice man--5664--2372
    yangyu is a good man
    yangyu is a nice man--5664--2372
    yangyu is a good man
    yangyu is a good man
    yangyu is a nice man--5664--2372'''
    
    

    5.父子进程的先后顺序

    # 父子进程的先后顺序
    from multiprocessing import Process
    from time import sleep
    
    def run(str1,str2):
        print("子进程启动+%s"%str1)
        sleep(3)
        print("子进程结束+%s"%str2)
    
    if __name__ == "__main__":
        print("父进程启动")
    
        p = Process(target=run, args=("start","end"))
        p.start()
    
        # 父进程的结束不能影响子进程,让父进程等待子进程的结束再执行父进程
        p.join()
        print("父进程结束")
    '''
    父进程启动
    子进程启动+start
    子进程结束+end
    父进程结束
    '''
    
    

    6.多个进程不能共享全局变量

    # 多个进程不能共享全局变量
    # 在子进程中修改全局变量对父进程中的全局变量没有影响
    # 在创建子进程时对全局变量做了一个备份,父进程中的子进程中的num是完全不同的两个变量
    from multiprocessing import Process
    num = 100
    def run():
        print("子进程开始")
        global num  # num = 100
        num += 1
        print(num)
        print("子进程结束")
    
    if __name__ == "__main__":
        print("父进程开始")
        p = Process(target=run)
        p.start()
        p.join()
        print("父进程结束--%d"%num)
    '''
    父进程开始
    子进程开始
    101
    子进程结束
    父进程结束--100
    '''
    
    

    7.启动多个子进程

    # 启动多个子进程
    from multiprocessing import Pool
    import os,time
    def run(name):
        print("子进程%d启动--%s" % (name, os.getpid()))
        start = time.time()
        time.sleep(3)
        end = time.time()
        print("子进程%d结束--%s--耗时%.2f" % (name, os.getpid(), end-start))
    
    if __name__ == "__main__":
        t1 = time.time()
        print("父进程启动")
        # 创建多个进程
        # 进程池
        # 表示可以同时执行的进程数量
        # Pool默认大小是cpu核心线程数,我的笔记本电脑是2核4线程(这里的线程就同时执行的进程),Pool()默认为4,默认同时执行4进程,总耗时为18.2s;改为2,总耗时为32.5s;改为8,总耗时14.1s;改为20,总耗时20.35s。所有一般就用核心数*线程数(2*4=8),执行速度最快。
        pp = Pool(8)
        for i in range(20):
            # 创建进程,放入进程池同意管理
            pp.apply_async(run, args=(i,))
        # 在调用join之前必须先调用close,调用close之后就不能再继续添加新的进程了
        pp.close()
        # 进程池对象调用join,会等待进程池中所有的子进程结束完毕再去执行父进程
        pp.join()
        print("父进程结束,总耗时为%s"%(time.time()-t1))
    '''
    父进程启动
    子进程0启动--9048
    子进程1启动--3648
    子进程2启动--7180
    子进程3启动--7888
    子进程4启动--8228
    子进程5启动--8664
    子进程6启动--8688
    子进程7启动--9432
    子进程0结束--9048--耗时3.01
    子进程8启动--9048
    子进程1结束--3648--耗时3.01
    子进程9启动--3648
    子进程2结束--7180--耗时3.01
    子进程10启动--7180
    子进程3结束--7888--耗时3.01
    子进程11启动--7888
    子进程4结束--8228--耗时3.01
    子进程12启动--8228
    子进程5结束--8664--耗时3.01
    子进程13启动--8664
    子进程6结束--8688--耗时3.01
    子进程14启动--8688
    子进程7结束--9432--耗时3.01
    子进程15启动--9432
    子进程8结束--9048--耗时3.07
    子进程16启动--9048
    子进程9结束--3648--耗时3.01
    子进程17启动--3648
    子进程10结束--7180--耗时3.01
    子进程18启动--7180
    子进程11结束--7888--耗时3.01
    子进程19启动--7888
    子进程12结束--8228--耗时3.01
    子进程13结束--8664--耗时3.01
    子进程14结束--8688--耗时3.01
    子进程15结束--9432--耗时3.01
    子进程16结束--9048--耗时3.01
    子进程17结束--3648--耗时3.01
    子进程18结束--7180--耗时3.04
    子进程19结束--7888--耗时3.01
    父进程结束,总耗时为14.196025133132935
    '''
    
    

    8.多进程文件拷贝

    1.普通文件拷贝

    # 实现文件的拷贝
    import os, time
    def copyFile(rPath, wPath):
        fr = open(rPath, "rb")
        fw = open(wPath, "wb")
        context = fr.read()
        fw.write(context)
        fr.close()
        fw.close()
    
    path = r"F:\PycharmProjects\Project\进程\file1\1905热门电影图片"
    toPath = r"F:\PycharmProjects\Project\进程\file2"
    
    # 读取path下的所有文件
    fileList = os.listdir(path)
    
    # 启动for循环去处理每个文件
    start = time.time()
    for fileName in fileList:
        copyFile(os.path.join(path,fileName), os.path.join(toPath, fileName))
    end = time.time()
    print("总耗时:%0.2f" % (end-start))  # 总耗时:14.68
    

    2.多进程文件拷贝

    import os, time
    from multiprocessing import Pool
    # 实现文件的拷贝
    def copyFile(rPath, wPath):
        fr = open(rPath, "rb")
        fw = open(wPath, "wb")
        context = fr.read()
        fw.write(context)
        fr.close()
        fw.close()
    
    path = r"F:\PycharmProjects\Project\进程\file1\1905热门电影图片"
    toPath = r"F:\PycharmProjects\Project\进程\file2"
    
    if __name__ == "__main__":
        # 读取path下的所有文件
        fileList = os.listdir(path)
        start = time.time()
        pp = Pool(4)
        for fileName in fileList:
            pp.apply_async(copyFile, args=(os.path.join(path, fileName), os.path.join(toPath, fileName)))
        pp.close()
        pp.join()
        end = time.time()
        print("总耗时:%0.2f" % (end - start))  # 总耗时:11.40
    

    9.封装进程对象

    1.创建yangyuProcess.py文件

    from multiprocessing import Process
    import os, time
    
    class YangyuProcess(Process):
        def __init__(self, name):
            Process.__init__(self)
            self.name = name
    
        def run(self):
            print("子进程(%s-%s)启动" % (self.name, os.getpid()))
    
            # 子进程的功能
            time.sleep(3)
    
            print("子进程(%s-%s)结束" % (self.name, os.getpid()))
    

    2.from yangyuProcess import YangyuProcess

    from yangyuProcess import YangyuProcess
    
    if __name__ == "__main__":
        print("父进程启动")
        # 创建子进程
        p = YangyuProcess("test")
        # 自动调用p进程对象的run方法
        p.start()
        p.join()
        print("父进程结束")
    '''
    打印结果:
    父进程启动
    子进程(test-3476)启动
    子进程(test-3476)结束
    父进程结束
    '''
    """
    这样写的好处:子进程的方法不用和父进程的方法写在一起,让主程序结构更清晰。
    """
    

    10.进程间的通信

    1.示例1

    from multiprocessing import Process, Queue
    import os,time
    
    def write(q):
        print("启动写子进程%s"%(os.getpid()))
        for chr in ["A","B","C","D"]:
            q.put(chr)
            time.sleep(1)
        print("结束写子进程%s"%(os.getpid()))
    
    def read(q):
        print("启动读子进程%s" % (os.getpid()))
        while True:
            value = q.get(True)
            print("value=" + value)
        print("结束读子进程%s" % (os.getpid()))
    
    
    if __name__ == "__main__":
        # 父进程创建队列,并传给子进程
        q = Queue()
        pw = Process(target=write, args=(q,))
        pr = Process(target=read, args=(q,))
    
        pw.start()
        pr.start()
    
        pw.join()
        pr.terminate()  # pr进程里是个死循环,无法等待其结束,只能强制结束
    
        print("父进程结束")
    
    '''
    启动写子进程7752
    启动读子进程7264
    value=A
    value=B
    value=C
    value=D
    结束写子进程7752
    父进程结束'''
    
    

    2.示例2

    from multiprocessing import Process, Queue
    import os,time
    
    def write(q):
        print("启动写子进程%s"%(os.getpid()))
        for chr in ["A","B","C","D"]:
            q.put(chr)
            print(chr)
        print("结束写子进程%s"%(os.getpid()))
    
    def read(q):
        print("启动读子进程%s" % (os.getpid()))
        while not q.empty():
            value = q.get(True)
            print("value=" + value)
            time.sleep(1)
        print("结束读子进程%s" % (os.getpid()))
    
    
    if __name__ == "__main__":
        print("父进程开始")
        # 父进程创建队列,并传给子进程
        q = Queue(4)
        pw = Process(target=write, args=(q,))
        pr = Process(target=read, args=(q,))
    
        pw.start()
        pr.start()
        pw.join()
        pr.join()
        print("父进程结束")
    
    '''
    父进程开始
    启动写子进程8228
    A
    B
    C
    D
    结束写子进程8228
    启动读子进程7472
    value=A
    value=B
    value=C
    value=D
    结束读子进程7472
    父进程结束
    '''
    
    展开全文
  • Qt 之运行一个实例进程

    千次阅读 2016-02-04 17:52:34
    只需要用户运行一个实例进程 用户可以同时运行多个实例进程 一个实例进程的软件有很多,例如:360、酷狗… 多个实例进程的软件也很多,例如:Visual Studio、Qt Ctretor、QQ…下面我们来介绍下如何实现一个实例进程...

    简述

    发布程序的时候,我们往往会遇到这种情况:

    1. 只需要用户运行一个实例进程
    2. 用户可以同时运行多个实例进程

    一个实例进程的软件有很多,例如:360、酷狗…
    多个实例进程的软件也很多,例如:Visual Studio、Qt Ctretor、QQ…

    下面我们来介绍下如何实现一个实例进程。

    | 版权声明:一去、二三里,未经博主允许不得转载。

    QSharedMemory

    使用共享内存来实现,key值唯一,一般可以用组织名+应用名来确定。

    首先,创建一个共享内存区,当第二个进程启动时,判断内存区数据是否建立,如果有,可以激活已打开的窗体,也可以退出。

    当程序crash的时候,不能及时清除共享区数据,导致程序以后不能正常启动。

    int main(int argc, char **argv)
    {
        QApplication app(argc, argv);
    
        QCoreApplication::setOrganizationName("Company");
        QCoreApplication::setApplicationName("AppName");
        QString strKey = QCoreApplication::organizationName() + QCoreApplication::applicationName();
    
        QSharedMemory sharedMemory(strKey);
        if (!sharedMemory.create(512, QSharedMemory::ReadWrite))
        {
            QMessageBox::information(NULL, QStringLiteral("提示"), QStringLiteral("程序已运行!"));
            exit(0);
        }
    
        MainWindow window;
        window.show();
    
        return app.exec();
    }

    QLocalServer

    QSingleApplication.h

    #ifndef SINGLE_APPLICATION_H
    #define SINGLE_APPLICATION_H
    
    #include <QApplication>
    
    class QLocalServer;
    
    class QSingleApplication : public QApplication
    {
        Q_OBJECT
    
    public:
        explicit QSingleApplication(int argc, char **argv);
        // 判断进程是否存在
        bool isRunning();
    
    private slots:
        void newLocalConnection();
    
    private:
        QLocalServer *m_pServer;
        bool m_bRunning;
    };
    
    #endif // SINGLE_APPLICATION_H

    QSingleApplication.cpp

    #include <QLocalSocket>
    #include <QLocalServer>
    #include <QFile>
    #include <QTextStream>
    #include "QSingleApplication.h"
    
    QSingleApplication::QSingleApplication(int argc, char **argv)
        : QApplication(argc, argv),
          m_bRunning(false)
    {
        QCoreApplication::setOrganizationName("Company");
        QCoreApplication::setApplicationName("AppName");
        QString strServerName = QCoreApplication::organizationName() + QCoreApplication::applicationName();
    
        QLocalSocket socket;
        socket.connectToServer(strServerName);
    
        if (socket.waitForConnected(500))
        {
            QTextStream stream(&socket);
            QStringList args = QCoreApplication::arguments();
    
            QString strArg = (args.count() > 1) ? args.last() : "";
            stream << strArg;
            stream.flush();
            qDebug() << "Have already connected to server.";
    
            socket.waitForBytesWritten();
    
            m_bRunning = true;
        }
        else
        {
            // 如果不能连接到服务器,则创建一个
            m_pServer = new QLocalServer(this);
            connect(m_pServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));
    
            if (m_pServer->listen(strServerName))
            {
                // 防止程序崩溃,残留进程服务,直接移除
                if ((m_pServer->serverError() == QAbstractSocket::AddressInUseError) && QFile::exists(m_pServer->serverName()))
                {
                    QFile::remove(m_pServer->serverName());
                    m_pServer->listen(strServerName);
                }
            }
        }
    }
    
    void QSingleApplication::newLocalConnection()
    {
        QLocalSocket *pSocket = m_pServer->nextPendingConnection();
        if (pSocket != NULL)
        {
            pSocket->waitForReadyRead(1000);
    
            QTextStream in(pSocket);
            QString strValue;
            in >> strValue;
            qDebug() << QString("The value is: %1").arg(strValue);
    
            delete pSocket;
            pSocket = NULL;
        }
    }
    
    bool QSingleApplication::isRunning()
    {
        return m_bRunning;
    }

    使用方式

    int main(int argc, char **argv)
    {
        QSingleApplication app(argc,argv);
        if (app.isRunning())
        {
            QMessageBox::information(NULL, QStringLiteral("提示"), QStringLiteral("程序已运行!"));
            exit(0);
        }
    
        MainWindow window;
        window.show();
    
        return app.exec();
    }

    QtSingleApplication

    QSingleApplication位于qt-solution里面,并不包含在Qt库中,遵循 LGPL 协议。

    文档、源码、示例见:QtSingleApplication

    任务列表

    运行程序时,遍历任务列表,查看是当前所有运行中的进程,如果当前进程位置在映射路径中可以找到,则说明程序已经运行,否则,未运行。

    更多参考

    展开全文
  • 进程与线程的关系 简单复习一下:一个”进程“代表中计算机中实际跑起来的一个程序,在现代操作系统...因此一个进程至少得有一个线程,我们把这个线程称之为”主线程“,也就是说,一个进程至少要有一个主线程。 ...
  • 一:结论 1.两个进程中分别产生生成两个独立的fd 2.两个进程可以任意对文件进行读写操作,操作系统并不保证写...6.一个进程对文件长度和内容的修改另外一个进程可以立即感知 二:文件描述符与打开文件的关系? 内核...
  • 端口号可以用来标识同一个主机上通信的不同应用程序,端口号+IP地址就可以组成一个套接字,用来标识一个进程 2.端口号的应用场景 在TCP/IP协议中,用“源IP地址”,“目的IP地址”,“源端口号”,“目的端口...
  • 单个进程监听多个端口单个进程创建多个 socket 绑定不同的端口,TCP, UDP 都行多个进程监听同一个端口(multiple processes listen on same port)方式1:通过 fork 创建子进程的方式可以实现,其他情况下不行。...
  • Linux 第一个进程

    千次阅读 2018-06-08 16:42:47
    它是内核运行后的第一个进程. 它的作用你可以在网上查一下.总的来说功能很多.包括 runlevel, 驱动, 启动服务啥地都会做,感觉事情很多.pid=2 :kthreadd:用于内核线程管理。pid=3 :migration,用于进程在不同的CPU...
  •  一是如何实现一个守护进程,二是如何检测一个进程是否活着,三是保证某一执行文件只有一个实例在运行。 /*  * 1.守护进程  */ 守护进程的最大特点就是脱离了中断,Linux提供了一个系统调用daemon(),要想自定义...
  • C#只启动一个进程

    千次阅读 2013-01-16 14:03:03
    保证软件只运行一次还是很有必要的,方法也很简单,只要判断进程中有无当前的进程名就可以了。 对于WPF的软件,在App.XAML.cs中判断。重写OnStartup方法就可以了。... /// 只打开一个进程 /// ///
  • 一个程序多个进程

    千次阅读 2011-04-08 18:20:00
     说白了就是,一个程序可以重复运行,开几个窗口,比如网游的“双开”,一个进程可以对应多个程序就是一个DLL文件可一被多个程序运用,比如DirectX9的动态链接库,就是,许多游戏都要有它才能运行。
  • Android多进程实现,一个APP多个进程

    千次阅读 2019-07-30 10:03:06
    相关文章: Android IPC机制(一)开启多进程(文章1:刘望舒大神的文章,1.3w阅读量,20赞) Android IPC机制(二)用Messenger进行...Android中,默认一个APK包就对应一个进程。 Android平台对每个进程有内存限...
  • 1,目的如图; 2,实现代码: //进程所在文件夹 ProcessStartInfo startInfo = new ProcessStartInfo(Settings.Default.texturePath + @"TexturePacker.exe"); //重定向输出 startInfo
  • 用PowerShell查找一个进程的父进程

    千次阅读 2015-06-18 22:27:15
    在Windows中,我们打开进程任务管理器的时候会发现有许许多多的进程,但是当你点击一个进程的时候就会发现他还包含有一些子进程,可能已经没有在做任何处理了,或者夜有可能是某些病毒木马恶意进程,一般没有专用的...
  • 最近项目中的一个计数程序,因为会计数,所以只能有一个进程在运行,否则计数速度会加快,而刚好又是一个守护进程。Steven的《unix环境高级编程》的守护进程中就有讲,单实例进程。 这种监控有很多,如果放在两年前...
  • Linux命令行下杀死一个进程

    万次阅读 2018-08-22 14:03:11
    top命令:可以实时动态地查看系统的整体运行情况,是一个综合了多方信息监测系统性能和运行信息的实用工具。通过top命令所提供的互动式界面,用热键可以管理。 输入top后可以看到如下的界面,实时显示进程情况。 ...
  • Linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗?...任何一个进程删除该文件时,另外一个进程不会立即出现读写失败 5.两个进程可以分别读取文件的不同部分而不会相互影响 6.一...
  • linux查看某一个进程的socket连接数

    千次阅读 2019-07-23 11:47:06
    ls /proc/18709/fd -l | grep socket: | wc -l 18709是进程ID 可以通过 ps aux | grep 进程名称 来获取到
  • Android多进程实现,一个APP多个进程
  • Linux 查看某一个进程占用内存情况

    千次阅读 2020-06-30 14:21:28
    Linux下查看某一个进程所占用的内存,首先可以通过ps命令找到进程id,比如ps-ef |grepkafka可以看到kafka这个程序的进程id    可以看到是2913,现在可以使用如下命令查看内存: top -p 2913    这样可以...
  • 编写一个守护进程

    千次阅读 2013-06-16 14:36:55
    守护进程-----也就是常说的Daemon进程,是linux后台的服务进程,是一个生存期较长的进程,独立于终端并且周期性的执行某种任务或等待处理某些任务。守护进程在系统引 导时载入时启动,在系统关闭时终止。linux下的...
  • 个进程都有一个标识符(PID)和一个句柄,系统和其他进程可以通过PID和进程的句柄对进程进行管理操作动态库的原理如:API函数CreateFile可执行代码在Kernel32.dll中,"内存分页管理"将多个虚拟内存分页映射到同一个物理...
  • 在 Linux 中杀死一个进程

    千次阅读 2018-06-25 10:40:34
    在 Linux 中,假如一个进程的 PID 为 3810,那么结束一个进程可以使用如下命令: $ kill -9 3810 以 Postman 为例,首先我们需要找到它的进程号,然后才能杀死。 查找进程号使用 ps 命令,不过有一个强大的参数 -...
  • 一、 kill函数 1. 用于向任何进程组或进程发送信号 #include signal.h> int kill(pid_t pid, int sig); ... 1. pid大于零时,pid是... pid等于零时,信号将送往所有与调用kill()的那个进程属同一个组的进程
  • 个进程可以监听同一个端口?

    千次阅读 2012-06-27 16:17:22
    多个socket绑定同一个端口,叫做端口复用 下列代码可以使用socket绑定多次 //SO_REUSEADDR选项就是可以实现端口重绑定的  if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)  {  ...
  • Java中main方法启动的是一个线程也是一个进程,一个java程序启动后它就是一个进程,进程相当于一个空盒,它只提供资源装载的空间,具体的调度并不是由进程来完成的,而是由线程来完成的。一个java程序从main开始之后...
  • 端口号可以用来标识同一个主机上通信的不同应用程序,端口号+IP地址就可以组成一个套接字,用来标识一个进程 2.端口号的应用场景 在TCP/IP协议中,用“源IP地址”,“目的IP地址”,“源端口号”,“目的端口号”,...
  • 个进程同时访问同一个文件

    万次阅读 2019-04-08 09:06:06
    对于多个进程打开同一文件的情况,每个进程都有它自己的文件表项(file对象),其中有它自己的文件位移量,所以对于多个进程读同一文件都能正确工作。但是,当多个进程写同一文件时,则可能产生预期不到的结果。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,000,720
精华内容 800,288
关键字:

一个进程可以