多线程

1. 线程的概念

    线程是程序执行流的最小单元,也称为轻量级进程。

2. 进程的概念 

    计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础

3. 线程与进程的关系

    一个进程至少有一个线程,一个线程只属于一个进程。进程是系统进行资源分配和调度的一个单位,线程是进程的一个实体,线程除了拥有再运行中必不可少的资源(如程序计数器,一组寄存器和栈)不拥有任何系统资源,只能使用所属进程的资源


4. windows环境多线程

    4.1 windows创建线程API

HANDLE WINAPI CreateThread(
    __in_opt  LPSECURITY_ATTRIBUTES lpThreadAttributes,
    __in      SIZE_T dwStackSize,
    __in      LPTHREAD_START_ROUTINE lpStartAddress,
    __in_opt  LPVOID lpParameter,
    __in      DWORD dwCreationFlags,
    __out_opt LPDWORD lpThreadId
    );

  • lpThreadAttributes

  指向LPSECURITY_ATTRIBUTES结构体的指针,默认设为NULL,让线程使用默认的安全性。如果希望所有子线程能够继承线程对象的句柄,则必须设定LPSECURITY_ATTRIBUTES结构体,将它的bInHeriHandle初始化未TRUE。

  • dwStackSize

    设置初始栈的大小,默认设为0。

  • lpStartAddress

  指向LPTHREAD_START_ROUTINE指向的函数指针,即为新线程的起始地址。该函数的名称任意,但是函数类型必须遵照下面声明的形式:

typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(
    LPVOID lpThreadParameter
    );

  • lpParameter

  新线程调用函数的命令行参数。

  • dwCreationFlags

  用于控制线程创建的附加标记。可以使两个值之一:CRETE_SUSPENDED或0。如果是SUSPENDED,那么线程创建后将处于暂停状态。如果是0,线程在创建后立即运行。

  • lpThreadId

  指向一个变量,用来接受线程的ID。如果对线程ID不感兴趣可以直接设为NULL。

  注意:CreateThread()函数传回的值有两个,第一个值是返回值HANDLE,这个值是线程的HANDLE,是线程所在的进程中的局部变量,在不同的进程中是不唯一的,所以你不能直接跨进程的把一个线程的HANDLE传给另外一个进程中的线程让其使用。第二个值是由lpThreadId传回的线程ID,此值是一个全局变量,可以独一无二的表示系统中任意进程中的某个线程。比如调用AttachThreadInput()或PostThreadMessage()就需要用线程ID,而不能用线程的HANDLE。

      4.2 等待函数

            等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止。

DWORD WaitForSingleObject(
     HANDLE hObject,
     DWORD dwMilliseconds
);
  • hObject

  标识一个能够支持被通知/未通知的内核对象(前面列出的任何一种对象都适用)。

  • dwMilliseconds

  允许该线程指明,为了等待该对象变为已通知状态,它将等待多长时间。(INFINITE为无限时间量,INFINITE已经定义为0xFFFFFFFF(或-1))

      4.3 windows实例

/
//\
//\            windwos多线程练习
//\            2017-05-26 cwp
//\
/

#include <stdio.h>
#include <windows.h>

// 线程函数
DWORD WINAPI ThreadFunc(LPVOID arg)
{
    printf("thread id:%d, ThreadFunc\n", GetCurrentThreadId());
    return NULL;
}

int main()
{
    printf("thread id:%d, man\n", GetCurrentThreadId());
    HANDLE handle = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
    printf("Thread id:%d, Wait ThreadFunc exit\n", GetCurrentThreadId());
    WaitForSingleObject(handle, INFINITE);
    CloseHandle(handle);
    return 0;
}

    4.4运行结果

5. linux多线程

    Linux系统内核只提供了轻量级进程的支持,并未实现线程模型。我们常用的LinuxThreads只是一个伪线程,是在用户级实现一个包括信号处理在内的线程管理机制。

    5.1 线程创建函数pthread_create

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

参数说明:

  • thread:指向pthread_create类型的指针,用于引用新创建的线程。
  • attr:用于设置线程的属性,一般不需要特殊的属性,所以可以简单地设置为NULL。
  • start_routine:传递新线程所要执行的函数地址。
  • arg:新线程所要执行的函数的参数。

  返回值:

  调用如果成功,则返回值是0;如果失败则返回错误代码。

  每个线程都有自己的线程ID,以便在进程内区分。线程ID在pthread_create调用时回返给创建线程的调用者;一个线程也可以在创建后使用pthread_self()调用获取自己的线程ID.

      5.2 线程等待函数pthread_join

int pthread_join(pthread_t thread, void **retval);

参数说明:

  • thread:pthread_create类型的指针,等待该线程运行结束。
  • retval:线程的返回值。

  返回值:

  调用如果成功,则返回值是0;如果失败则返回错误代码。

      5.3 示例代码

/
//\
//\        linux多线程示例
//\        2017-05-25 cwp
//\
/

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include <sys/syscall.h>  
#define gettid() syscall(__NR_gettid) 

// 线程1
void *ThreadFunc1(void *arg)
{
    printf("Process id :%lu, Thread id : %lu, ThreadFunc1\n", getpid(), gettid());
    return NULL;
}

// 线程2
void *ThreadFunc2(void *arg)
{
    printf("Process id :%lu, Thread id : %lu, ThreadFunc2\n", getpid(), gettid());
    char *tmp = new char[strlen("ThreadFunc2") + 1];
    memset(tmp, 0, 10);
    sprintf(tmp, "ThreadFunc2");
    return (void *)tmp;
}

int main()
{
    pthread_t id[2];
    // 创建线程1
    int ret = pthread_create(&id[0], NULL, ThreadFunc1, NULL);
    if (ret != 0)
    {
    printf("Create thread1 failed!\n");
    return 0;
    }

    // 创建线程2
    ret = pthread_create(&id[1], NULL, ThreadFunc2, NULL);
    if (ret != 0)
    {
    printf("Create thread2 failed!\n");
    return 0;
    }

    // 等待线程1退出
    pthread_join(id[0], NULL);

    // 等待线程2退出,并打印线程2的返回值
    void *value = NULL;
    pthread_join(id[1], &value);
    printf("Process id :%lu, Thread id : %lu, man value : %s\n", getpid(), gettid(), (char *)value);
    delete [] (char *)value;
    
    return 0;
}

注:该博文同时更新博客园(风逝_陈)  http://www.cnblogs.com/wpchen/p/6911078.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值