0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是多线程编程?Linux下的多线程编程

Linux大陆 来源:Linux大陆 作者:Linux大陆 2023-05-06 10:58 次阅读

什么是多线程编程

1、线程和进程的区别

进程是指正在运行的程序,它拥有独立的内存空间和系统资源,不同进程之间的数据不共享。

线程是进程内的执行单元,它与同一进程内的其他线程共享进程的内存空间和系统资源。

2、多线程的优势和应用场景

多线程是一种并发编程方式,它的优势包括:

提高程序的响应速度和运行效率(多核CPU下的多线程)

充分利用CPU资源,提高系统的利用率

支持多个任务并行执行,提高程序的可扩展性和可维护性

Linux下的多线程编程

Linux下C语言多线程编程依赖于pthread多线程库。pthread库是Linux的多线程库,是POSIX标准线程API的实现,它提供了一种创建和操纵线程的方法,以及一些同步机制,如互斥锁、条件变量等。

头文件:

#include

编译链接需要链接链接库 pthread。

一、线程的基本操作

1、pthread_create

/**
*@brief创建一个线程
*
*Detailedfunctiondescription
*
*@param[in] thread:一个指向线程标识符的指针,线程调用后,该值被设置为线程ID;pthread_t为unsigned long int
*@param[in]attr:用来设置线程属性
*@param[in]start_routine:线程函数体,线程创建成功后,thread指向的内存单元从该地址开始运行
*@param[in]arg:传递给线程函数体的参数
*
*@return线程创建成功,则返回0,失败则返回错误码,并且thread内容是未定义的
*/
intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg);

例子test.c:创建一个线程,每1s打印一次。

#include
#include
#include
#include

staticpthread_ts_thread_id;
staticunsignedchars_thread_running=0;

void*thread_fun(void*arg)
{
s_thread_running=1;
while(s_thread_running)
{
printf("threadrun...
");
sleep(1);
}

pthread_exit(NULL);
}

intmain(void)
{
intret=0;

printf("BeforeThread
");
ret=pthread_create(&s_thread_id,NULL,thread_fun,NULL);
if(ret!=0)
{
printf("thread_createerror!
");
exit(EXIT_FAILURE);
}

ret=pthread_join(s_thread_id,NULL);///< 阻塞等待线程结束
    if (ret != 0)
    {
        printf("pthread_join error!
");
        exit(EXIT_FAILURE);
    }
    printf("After Thread
");
    exit(EXIT_SUCCESS);
}

编译、运行:

gcctest.c-otest-lpthread
83b7cd30-ebb9-11ed-90ce-dac502259ad0.png

2、pthread_join

/**
*@brief等待某个线程结束
*
*Detailedfunctiondescription:这是一个线程阻塞函数,调用该函数则等到线程结束才继续运行
*
*@param[in]thread:某个线程的ID
*@param[in]retval:用于获取线程start_routine的返回值
*
*@return线程创建成功,则返回0,失败则返回错误码,并且thread内容是未定义的
*/
intpthread_join(pthread_tthread,void**retval);

例子test.c:创建一个线程,进行一次加法运算就返回。

#include
#include
#include
#include

staticpthread_ts_thread_id;
staticunsignedchars_thread_running=0;

void*thread_fun(void*arg)
{
staticintres=0;
inta=1,b=2;

res=a+b;
sleep(1);
printf("threadrun,a+b=%d,addr=%p
",res,&res);

pthread_exit(&res);
}

intmain(void)
{
intret=0;
int*retval=NULL;

printf("BeforeThread
");
ret=pthread_create(&s_thread_id,NULL,thread_fun,NULL);
if(ret!=0)
{
printf("pthread_createerror!
");
exit(EXIT_FAILURE);
}

ret=pthread_join(s_thread_id,(void**)&retval);///< 阻塞等待线程结束
    if (ret != 0)
    {
        printf("pthread_join error!
");
        exit(EXIT_FAILURE);
    }
    if (retval != NULL)
    {
        printf("After Thread, retval = %d, addr = %p
", (int)*retval, retval);
    }

    exit(EXIT_SUCCESS);
}

编译、运行:

83c09d52-ebb9-11ed-90ce-dac502259ad0.png

3、pthread_exit

/**
*@brief退出线程
*
*Detailedfunctiondescription
*
*@param[in]retval:它指向的数据将作为线程退出时的返回值
*
*@returnvoid
*/
voidpthread_exit(void*retval);

线程将指定函数体中的代码执行完后自行结束;

线程执行过程中,被同一进程中的其它线程(包括主线程)强制终止;

线程执行过程中,遇到 pthread_exit() 函数结束执行。

例子test.c:创建一个线程,每个1s打印一次,打印超过5次时调用pthread_exit退出。

#include
#include
#include
#include

staticpthread_ts_thread_id;
staticunsignedchars_thread_running=0;
conststaticchar*thread_exit_str="thread_exitok!";

void*thread_fun(void*arg)
{
staticintcnt=0;

s_thread_running=1;
while(s_thread_running)
{
cnt++;
if(cnt>5)
{
pthread_exit((void*)thread_exit_str);
}
printf("threadrun...
");
sleep(1);
}

pthread_exit(NULL);
}

intmain(void)
{
intret=0;
void*thread_res=NULL;

printf("BeforeThread
");
ret=pthread_create(&s_thread_id,NULL,thread_fun,NULL);
if(ret!=0)
{
printf("thread_createerror!
");
exit(EXIT_FAILURE);
}

ret=pthread_join(s_thread_id,(void**)&thread_res);
if(ret!=0)
{
printf("thread_joinerror!
");
exit(EXIT_FAILURE);
}
printf("AfterThread,thread_res=%s
",(char*)thread_res);
exit(EXIT_SUCCESS);
}

编译、运行:

83ceb22a-ebb9-11ed-90ce-dac502259ad0.png

使用return退出线程与使用pthread_exit退出线程的区别?

return为通用的函数退出操作,pthread_exit专用与线程,既然pthread库有提供专门的函数,自然用pthread_exit会好些,虽然使用return也可以。

看看return退出线程与使用pthread_exit退出线程的具体区别:退出主线程。使用pthread_exit退出主线程只会终止当前线程,不会影响进程中其它线程的执行;使用return退出主线程,主线程退出执行很快,所有线程都会退出。

例子:使用pthread_exit退出主线程

#include
#include
#include
#include

staticpthread_ts_thread_id;
staticunsignedchars_thread_running=0;
conststaticchar*thread_exit_str="thread_exitok!";

void*thread_fun(void*arg)
{
sleep(1);
printf("thread_funrun...
");
pthread_exit(NULL);
}

intmain(void)
{
intret=0;
void*thread_res=NULL;

printf("BeforeThread
");
ret=pthread_create(&s_thread_id,NULL,thread_fun,NULL);
if(ret!=0)
{
printf("thread_createerror!
");
exit(EXIT_FAILURE);
}

printf("mainthreadexit
");
pthread_exit(NULL);
}

编译、运行:

83d7f89e-ebb9-11ed-90ce-dac502259ad0.png

例子:使用return退出主线程

#include
#include
#include
#include

staticpthread_ts_thread_id;
staticunsignedchars_thread_running=0;
conststaticchar*thread_exit_str="thread_exitok!";

void*thread_fun(void*arg)
{
sleep(1);
printf("thread_funrun...
");
pthread_exit(NULL);
}

intmain(void)
{
intret=0;
void*thread_res=NULL;

printf("BeforeThread
");
ret=pthread_create(&s_thread_id,NULL,thread_fun,NULL);
if(ret!=0)
{
printf("thread_createerror!
");
exit(EXIT_FAILURE);
}

printf("mainthreadexit
");

return0;
}

编译、运行:

83e03c8e-ebb9-11ed-90ce-dac502259ad0.png

4、pthread_self

/**
*@brief用来获取当前线程ID
*
*Detailedfunctiondescription
*
*@param[in]void
*
*@return返回线程id
*/
pthread_tpthread_self(void);

例子:

#include
#include
#include
#include

staticpthread_ts_thread_id;
staticunsignedchars_thread_running=0;
conststaticchar*thread_exit_str="thread_exitok!";

void*thread_fun(void*arg)
{
staticintcnt=0;

s_thread_running=1;
while(s_thread_running)
{
cnt++;
if(cnt>5)
{
pthread_exit((void*)thread_exit_str);
}
printf("threadrun(tid=%ld)...
",pthread_self());
sleep(1);
}

pthread_exit(NULL);
}

intmain(void)
{
intret=0;
void*thread_res=NULL;

pid_tpid=getpid();
printf("pid=%d
",pid);

printf("BeforeThread
");
ret=pthread_create(&s_thread_id,NULL,thread_fun,NULL);
if(ret!=0)
{
printf("thread_createerror!
");
exit(EXIT_FAILURE);
}

ret=pthread_join(s_thread_id,(void**)&thread_res);
if(ret!=0)
{
printf("thread_joinerror!
");
exit(EXIT_FAILURE);
}
printf("AfterThread,thread_res=%s
",(char*)thread_res);
exit(EXIT_SUCCESS);
}

编译、运行:

83eb089e-ebb9-11ed-90ce-dac502259ad0.png

5、pthraad_detach

/**
*@brief分离线程
*
*Detailedfunctiondescription:分离线程,线程结束是系统自动回收线程的资源
*
*@param[in]thread:某个线程的ID
*
*@return成功时返回0,失败返回其他值
*/
intpthread_detach(pthread_tthread);

pthread_create创建的线程有两种状态:joinable(可结合的)和unjoinable(不可结合的/分离的)。默认是joinable 状态。

一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的,所以以默认的属性创建线程时,创建的线程时可结合的,我们需要对线程退出时调用pthread_join对线程资源进行回收。只有当pthread_join函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。

一个不可结合的线程,线程结束后会自动释放占用资源。

因为pthread_join是一个阻塞的操作,而大多数时候主线程并不希望因为调用pthread_join而阻塞,并且大多数情况下不会使用线程函数体的返回值,所以这时候可以把线程创建为不可结合的/分离的。

把线程创建为不可结合的/分离的有两种方式:

在创建线程之后,使用pthraad_detach分离线程。

在创建线程之前,使用pthread_attr_setdetachstate设置线程以不可结合的/分离的状态创建。

例子:在创建线程之后,使用pthraad_detach分离线程。

#include
#include
#include
#include

staticpthread_ts_thread_id;
staticunsignedchars_thread_running=0;

void*thread_fun(void*arg)
{
s_thread_running=1;
while(s_thread_running)
{
printf("childthreadrun...
");
sleep(1);
}

pthread_exit(NULL);
}

intmain(void)
{
intret=0;

printf("BeforeThread
");
ret=pthread_create(&s_thread_id,NULL,thread_fun,NULL);
if(ret!=0)
{
printf("thread_createerror!
");
exit(EXIT_FAILURE);
}

ret=pthread_detach(s_thread_id);
if(ret!=0)
{
printf("pthread_detacherror!
");
exit(EXIT_FAILURE);
}
printf("AfterThread
");

while(1)
{
printf("mainthreadrun...
");
sleep(1);
}

exit(EXIT_SUCCESS);
}

编译、运行:

83f4b81c-ebb9-11ed-90ce-dac502259ad0.png

pthread_join与pthraad_detach的区别:

pthread_detach()即主线程与子线程分离,两者相互不干涉,子线程结束同时子线程的资源自动回收。

pthread_join()即是子线程合入主线程,主线程会一直阻塞,直到子线程执行结束,然后回收子线程资源,并继续执行。

6、pthread_attr_init

/**
*@brief初始化一个线程对象的属性
*
*Detailedfunctiondescription
*
*@param[in]attr:指向一个线程属性的指针
*
*@return成功时返回0,失败返回其他值
*/
intpthread_attr_init(pthread_attr_t*attr);

如果不设置线程属性,线程则以默认属性进行创建,默认的属性值如:

83ff653c-ebb9-11ed-90ce-dac502259ad0.png

例子:在创建线程之前,使用pthread_attr_setdetachstate设置线程以不可结合的/分离的状态创建。

#include
#include
#include
#include

staticpthread_ts_thread_id;
staticunsignedchars_thread_running=0;

void*thread_fun(void*arg)
{
s_thread_running=1;
while(s_thread_running)
{
printf("threadrun...
");
sleep(1);
}

pthread_exit(NULL);
}

intmain(void)
{
intret=0;

printf("BeforeThread
");
pthread_attr_tattr;
ret=pthread_attr_init(&attr);
if(ret!=0)
{
printf("pthread_attr_initerror!
");
exit(EXIT_FAILURE);
}
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);///< 线程以分离的状态创建
    ret = pthread_create(&s_thread_id, &attr, thread_fun, NULL);
    if (ret != 0)
    {
        printf("thread_create error!
");
        exit(EXIT_FAILURE);
    }
    printf("After Thread
");
    pthread_attr_destroy(&attr);  ///< 销毁线程属性结构

    while (1)
    {
        sleep(1);
    }
    
    exit(EXIT_SUCCESS);
}

二、互斥锁(mutex)的使用

互斥锁用于保护一些公共资源。一些公共资源有可能会被多个线程共同使用,如果不做资源保护,可能会产生意想不到的bug。

一个线程,如果需要访问公共资源,需要获得互斥锁并对其加锁,资源在在锁定过程中,如果其它线程对其进行访问,也需要获得互斥锁,如果获取不到,线程只能进行阻塞,直到获得该锁的线程解锁。

互斥锁API:

#include
///< 创建互斥对象,用指定的初始化属性初始化互斥对象  
int pthread_mutex_init(pthread_mutex_t *mutex,  
                                       const pthread_mutex_attr_t *mutexattr);  

///< 加锁  
int pthread_mutex_lock(pthread_mutex_t *mutex);  

///< 解锁  
int pthread_mutex_unlock(pthread_mutex_t *mutex);  

///< 加锁,但是如果对象已经上锁则返回EBUSY错误代码而不阻塞  
int pthread_mmutex_trylock(pthread_mutex_t *mutex);  

///< 析构并释放mutex相关资源  
int pthread_mutex_destroy(pthread_mutex_t *mutex);  

互斥锁有两种创建方式:

静态创建:

pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;

动态创建:

pthread_mutex_tmutex;
pthread_mutex_init(&mutex,NULL);

pthread互斥锁属性包括:

PTHREAD_MUTEX_TIMED_NP:这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将会形成一个等待队列,并在解锁后按优先级获得锁。这种策略可以确保资源分配的公平性。

PTHREAD_MUTEX_RECURSIVE_NP:嵌套锁。允许同一个线程对同一个锁成功获得多次,并通过unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。

PTHREAD_MUTEX_ERRORCHECK_NP:检错锁。如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同,这样就保证了当不允许多次加锁时不会出现最简单情况下的死锁。

PTHREAD_MUTEX_ADAPTIVE_NP:适应锁,动作最简单的锁类型,仅等待一小段时间,如果不能获得锁就放弃等待

互斥锁使用形式:

pthread_mutex_tmutex;
pthread_mutex_init(&mutex,NULL);///< 初始化互斥锁
pthread_mutex_lock(&mutex);       ///< 加锁
///< 操作公共资源
pthread_mutex_unlock(&mutex);     ///< 解锁
pthread_mutex_destroy(&mutex);    ///< 销毁互斥锁

例子:

#include
#include
#include
#include

staticpthread_ts_thread1_id;
staticpthread_ts_thread2_id;
staticunsignedchars_thread1_running=0;
staticunsignedchars_thread2_running=0;

staticpthread_mutex_ts_mutex;
staticints_cnt=0;

void*thread1_fun(void*arg)
{
printf("[%s]pthread_mutex_lock------s_cnt=%d
",__FUNCTION__,s_cnt);
pthread_mutex_lock(&s_mutex);///< 加锁
    for (size_t i = 0; i < 100; i++)
    {
        s_cnt++;
    }
    printf("[%s]pthread_mutex_unlock ------ s_cnt = %d
", __FUNCTION__, s_cnt);
    pthread_mutex_unlock(&s_mutex);  ///< 解锁
    
    pthread_exit(NULL);
}

void *thread2_fun(void *arg)
{
    printf("[%s]pthread_mutex_lock ------ s_cnt = %d
", __FUNCTION__, s_cnt);
    pthread_mutex_lock(&s_mutex);    ///< 加锁
    for (size_t i = 0; i < 100; i++)
    {
        s_cnt++;
    }
    printf("[%s]pthread_mutex_unlock ------ s_cnt = %d
", __FUNCTION__, s_cnt);
    pthread_mutex_unlock(&s_mutex);  ///< 解锁
    
    pthread_exit(NULL);
}

int main(void)
{
    int ret = 0;

    ///< 创建互斥量
    ret = pthread_mutex_init(&s_mutex, NULL);
    if (ret != 0)
    {
        printf("pthread_mutex_init error!
");
        exit(EXIT_FAILURE);
    }

    ///< 创建线程1
    ret = pthread_create(&s_thread1_id, NULL, thread1_fun, NULL);
    if (ret != 0)
    {
        printf("thread1_create error!
");
        exit(EXIT_FAILURE);
    }
    ret = pthread_join(s_thread1_id, NULL); ///< 阻塞等待线程结束
    if (ret != 0)
    {
        printf("pthread1_join error!
");
        exit(EXIT_FAILURE);
    }

    ///< 创建线程2
    ret = pthread_create(&s_thread2_id, NULL, thread2_fun, NULL);
    if (ret != 0)
    {
        printf("thread2_create error!
");
        exit(EXIT_FAILURE);
    }
    ret = pthread_join(s_thread2_id, NULL); ///< 阻塞等待线程结束
    if (ret != 0)
    {
        printf("pthread2_join error!
");
        exit(EXIT_FAILURE);
    }

    printf("main thread, s_cnt = %d
", s_cnt);

    ret = pthread_mutex_destroy(&s_mutex);
    {
        printf("pthread_mutex_destroy error!
");
        exit(EXIT_FAILURE);
    }

    return 0;
}

编译、运行:

84066468-ebb9-11ed-90ce-dac502259ad0.png

三、条件变量的使用

条件变量是在线程中以睡眠的方式等待某一条件的发生,是利用线程间共享的全局变量进行同步的一种机制。

条件变量是线程可用的一种同步机制,条件变量给多个线程提供了一个会合的场所,条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定的条件发生。

条件变量API:

#include
///< 条件变量初始化
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

///< 销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond);

///< 等待条件变量
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

///< 带有超时功能的 等待条件变量
int pthread_cond_timedwait(pthread_cond_t *restrict cond, 
      pthread_mutex_t *restrict mutex,
      const struct timespec *restrict tsptr);

///< 通知条件变量,唤醒至少1个等待该条件的线程
int pthread_cond_signal(pthread_cond_t *cond);

///< 通知条件变量,广播唤醒等待该条件的所有线程
int pthread_cond_broadcast(pthread_cond_t *cond);

假如有两个线程,线程1依赖于某个变量才能执行相应的操作,而这个变量正好是由线程2来改变的。这种情况下有两种方案编写程序:

方案一:线程1轮询的方式检测这个变量是否变化,变化则执行相应的操作。

方案二:使用条件变量的方式。线程1等待线程2满足条件时进行唤醒。

其中,方案一比较浪费CPU资源。

条件变量的例子:创建两个线程,线程1对全局计数变量cnt从0开始进行自增操作。线程2打印5的倍数,线程1打印其它数。

#include
#include
#include
#include

staticpthread_ts_thread1_id;
staticpthread_ts_thread2_id;
staticunsignedchars_thread1_running=0;
staticunsignedchars_thread2_running=0;

staticpthread_mutex_ts_mutex;
staticpthread_cond_ts_cond;
staticints_cnt=0;

void*thread1_fun(void*arg)
{
s_thread1_running=1;
while(s_thread1_running)
{
pthread_mutex_lock(&s_mutex);///< 加锁
        s_cnt++;
        pthread_mutex_unlock(&s_mutex);  ///< 解锁

        if (s_cnt % 5 == 0)
        {
            pthread_cond_signal(&s_cond);  ///< 唤醒其它等待该条件的线程
        }
        else
        {
            printf("[%s]s_cnt = %d
", __FUNCTION__, s_cnt);
        }

        usleep(100 * 1000);
    }
    
    pthread_exit(NULL);
}

void *thread2_fun(void *arg)
{
    s_thread2_running = 1;
    while (s_thread2_running)
    {
        pthread_mutex_lock(&s_mutex);    ///< 加锁
        while (s_cnt % 5 != 0)
        {
            pthread_cond_wait(&s_cond, &s_mutex);   ///< 等待条件变量
        }
        
        printf("[%s]s_cnt = %d
", __FUNCTION__, s_cnt);
        pthread_mutex_unlock(&s_mutex);  ///< 解锁
        
        usleep(200 * 1000);
    }
    
    pthread_exit(NULL);
}

int main(void)
{
    int ret = 0;

    ///< 创建互斥量
    ret = pthread_mutex_init(&s_mutex, NULL);
    if (ret != 0)
    {
        printf("pthread_mutex_init error!
");
        exit(EXIT_FAILURE);
    }

    ///< 创建条件变量
    ret = pthread_cond_init(&s_cond, NULL);
    if (ret != 0)
    {
        printf("pthread_cond_init error!
");
        exit(EXIT_FAILURE);
    }

    ///< 创建线程1
    ret = pthread_create(&s_thread1_id, NULL, thread1_fun, NULL);
    if (ret != 0)
    {
        printf("thread1_create error!
");
        exit(EXIT_FAILURE);
    }
    ret = pthread_detach(s_thread1_id);
    if (ret != 0)
    {
        printf("s_thread1_id error!
");
        exit(EXIT_FAILURE);
    }

    ///< 创建线程2
    ret = pthread_create(&s_thread2_id, NULL, thread2_fun, NULL);
    if (ret != 0)
    {
        printf("thread2_create error!
");
        exit(EXIT_FAILURE);
    }
    ret = pthread_detach(s_thread2_id);
    if (ret != 0)
    {
        printf("s_thread2_id error!
");
        exit(EXIT_FAILURE);
    }

    while (1)
    {
        sleep(1);
    }

    return 0;
}

编译、运行:

8415bce2-ebb9-11ed-90ce-dac502259ad0.png






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11296

    浏览量

    209348
  • C语言
    +关注

    关注

    180

    文章

    7604

    浏览量

    136710
  • 编程
    +关注

    关注

    88

    文章

    3614

    浏览量

    93692
  • gcc编译器
    +关注

    关注

    0

    文章

    78

    浏览量

    3381

原文标题:Hello系列 | 多线程编程基础!

文章出处:【微信号:Linux大陆,微信公众号:Linux大陆】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux多线程编程手册

    Linux多线程编程手册
    发表于 11-07 10:17

    嵌入式Linux多线程编程

    嵌入式Linux多线程编程-学习资源-华清远见清远见嵌入式学院:清远见嵌入式学院:《嵌入式应用程序设计》——第5 章 嵌入式Linux 多线程
    发表于 11-05 06:54

    QNX环境多线程编程

    介绍了QNX 实时操作系统和多线程编程技术,包括线程间同步的方法、多线程程序的分析步骤、线程基本程序结构以及实用编译方法。QNX 是由加拿大
    发表于 08-12 17:37 30次下载

    linux多线程编程课件

    电子发烧友为您提供了linux多线程编程课件,希望对您学习 linux 有所帮助。部分内容如下: *1、多线程模型在单处理器模型和多处理器系
    发表于 07-10 11:58 0次下载

    linux多线程编程开发

    本文中我们针对 Linux多线程编程的主要特性总结出 5 条经验,用以改善 Linux 多线程编程
    发表于 12-26 14:24 55次下载
    <b class='flag-5'>linux</b><b class='flag-5'>多线程</b><b class='flag-5'>编程</b>开发

    MFC多线程编程

    计算机上的上位机制作工具语言之MFC多线程编程
    发表于 09-01 14:55 0次下载

    VC-MFC多线程编程详解

    VC编程中关于 MFC多线程编程的详解文档
    发表于 09-01 15:01 0次下载

    Windows多线程编程

    计算机上的上位机制作工具语言之Windows多线程编程,感兴趣的可以看看。
    发表于 09-01 15:27 0次下载

    linux多线程编程技术

    (process)中只允许有一个线程,这样多线程就意味着多进程。现在,多线程技术已经被许多操作系统所支持,包括Windows/NT,当然,也包括Linux。 为什么有了进程的概念后,还
    发表于 10-24 16:01 5次下载

    什么是多线程编程?多线程编程基础知识

    摘要:多线程编程是现代软件技术中很重要的一个环节。要弄懂多线程,这就要牵涉到多进程。本文主要以多线程编程以及
    发表于 12-08 16:30 1.3w次阅读

    关于Linux多线程编程技术学习总结

    Linux多线程编程技术 作为一个IT人员,不断的学习和总结是我们这个职业习惯,所以我会将每个阶段的学习都会通过一点的总结来记录和检测自己的学习效果,今天为大家总结了关于
    发表于 04-22 03:12 2202次阅读
    关于<b class='flag-5'>Linux</b><b class='flag-5'>下</b><b class='flag-5'>多线程</b><b class='flag-5'>编程</b>技术学习总结

    Linux多线程编程

    的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。  下面我们先来尝试编写一个简单的多线程程序。2 简单的多线程编程  
    发表于 04-02 14:43 605次阅读

    Linux多线程编程的知识点

    Hello、Hello大家好,我是木荣,今天我们继续来聊一聊Linux多线程编程中的重要知识点,详细谈谈多线程中同步和互斥机制。
    发表于 04-26 17:27 599次阅读
    <b class='flag-5'>Linux</b>中<b class='flag-5'>多线程</b><b class='flag-5'>编程</b>的知识点

    mfc多线程编程实例

    (图形用户界面)应用程序的开发。在这篇文章中,我们将重点介绍MFC中的多线程编程多线程编程在软件开发中非常重要,它可以实现程序的并发执行,提高程序的效率和响应速度。MFC提供了丰富
    的头像 发表于 12-01 14:29 1503次阅读

    socket 多线程编程实现方法

    在现代网络编程中,多线程技术被广泛应用于提高服务器的并发处理能力。Socket编程是网络通信的基础,而将多线程技术应用于Socket编程,可
    的头像 发表于 11-12 14:16 340次阅读