线程pthread和进程Process相关

本文深入探讨了POSIX线程(Pthreads)的三大核心功能:线程管理、互斥量和条件变量,通过实例展示了如何使用Pthreads进行线程同步。同时,文章对比了线程与进程的差异,特别关注线程退出机制及进程间通信(IPC)的不同方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

与线程pthread相关:

一、POSIX 多线程程序设计:https://blog.youkuaiyun.com/future_fighter/article/details/3865071#pthreads_overvie

Pthreads API中的函数可以非正式的划分为三大类:

(1)线程管理(Thread management): 第一类函数直接用于线程:创建(creating),分离(detaching),连接(joining)等等。包含了用于设置和查询线程属性(可连接,调度属性等)的函数。  


(2)互斥量(Mutexes): 第二类函数是用于线程同步的,称为互斥量(mutexes),是"mutual exclusion"的缩写。Mutex函数提供了创建,销毁,锁定和解锁互斥量的功能。同时还包括了一些用于设定或修改互斥量属性的函数。

例程如下:

用四个线程计算a[i]*b[i]积的和dotstr.sum,四个线程分别计算 i的取值为 i =[0...99], [100...199], [200...299], [300...399]

#include <pthread.h>
#include <stdio.h>
#include <malloc.h>
#include <iostream>

using namespace std;

typedef struct
{
           double          *a;
           double          *b;
           double         sum;
           int     veclen;
} DOTDATA;

#define NUMTHRDS 4 
#define VECLEN 10 
DOTDATA dotstr;
pthread_t callThd[NUMTHRDS];
pthread_mutex_t mutexsum;

void *dotprod(void *arg)
{
           int i, start, end, len ;
           long offset;
           double mysum, *x, *y;
           offset = (long)arg;

           len = dotstr.veclen;
           start = offset*len;
           end   = start + len;
           x = dotstr.a;
           y = dotstr.b;

           mysum = 0;
           for (i=start; i<end ; i++)
                {
                  mysum += (x[i] * y[i]);
                }

           pthread_mutex_lock (&mutexsum);
           dotstr.sum += mysum;
           cout << "dotstr.sum = " << dotstr.sum << endl;
           pthread_mutex_unlock (&mutexsum);

           pthread_exit((void*) 0);
}

int main (int argc, char *argv[])
{
  	long i;
           double *a, *b;
           void *status;
           pthread_attr_t attr;

           /* Assign storage and initialize values */
           a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
           b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));

           for (i=0; i<VECLEN*NUMTHRDS; i++)
           {
                 a[i]=1.0;
                 b[i]=a[i];
           }

           dotstr.veclen = VECLEN;
           dotstr.a = a;
           dotstr.b = b;
           dotstr.sum=0;

           pthread_mutex_init(&mutexsum, NULL);

           /* Create threads to perform the dotproduct  */
           pthread_attr_init(&attr);
           pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

                for(i=0; i<NUMTHRDS; i++)
                {
                        pthread_create( &callThd[i], &attr, dotprod, (void *)i);
                }

                pthread_attr_destroy(&attr);

                        /* Wait on the other threads */
                for(i=0; i<NUMTHRDS; i++)
                {
                          pthread_join( callThd[i], &status);
                }

           /* After joining, print out the results and cleanup */
           printf ("Sum =  %f /n", dotstr.sum);
           free (a);
           free (b);
           pthread_mutex_destroy(&mutexsum);
           pthread_exit(NULL);
}

(3)条件变量(Condition variables):第三类函数处理共享一个互斥量的线程间的通信,基于程序员指定的条件。这类函数包括指定的条件变量的创建,销毁,等待和受信(signal)。设置查询条件变量属性的函数也包含其中。

  条件变量用于线程同步。

例子:线程[0]和[1] 对全局变量count累加,当count达到条件 count =  COUNT_LIMI(12)时,触发线程[2]运行:

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h>
 
#define NUM_THREADS  2
#define TCOUNT 10 
#define COUNT_LIMIT 12
 
int     count = 0; 
int     thread_ids[3] = {0,1,2}; 
pthread_mutex_t count_mutex; 
pthread_cond_t count_threshold_cv; 
 
void *inc_count(void *idp)  
{ 
  int j,i; 
  double result=0.0; 
  int *my_id = (int *)idp; 
 
  for (i=0; i<TCOUNT; i++) { 
    pthread_mutex_lock(&count_mutex); 
    count++; 
 
    /*  
    Check the value of count and signal waiting thread when condition is 
    reached.  Note that this occurs while mutex is locked.  
    */ 
    if (count == COUNT_LIMIT) { 
      pthread_cond_signal(&count_threshold_cv); 
      printf("inc_count(): thread %d, count = %d  Threshold reached.\n", *my_id, count); 
      } 
    printf("inc_count(): thread %d, count = %d \n", *my_id, count); 
    pthread_mutex_unlock(&count_mutex); 
 
    /* Do some work so threads can alternate on mutex lock */ 
    for (j=0; j<1000; j++) 
      result = result + (double)random(); 
    } 
   pthread_exit(NULL); 
} 
 
void *watch_count(void *idp)  
{ 
  int  *my_id = (int *)idp; 

 
  printf("Starting watch_count(): thread %d\n", *my_id); 
 
  /* 
  Lock mutex and wait for signal.  Note that the pthread_cond_wait  
  routine will automatically and atomically unlock mutex while it waits.  
  Also, note that if COUNT_LIMIT is reached before this routine is run by 
  the waiting thread, the loop will be skipped to prevent pthread_cond_wait 
  from never returning.  
  */ 
  pthread_mutex_lock(&count_mutex); 
  if (count<COUNT_LIMIT) { 
    pthread_cond_wait(&count_threshold_cv, &count_mutex); 
    printf("watch_count(): thread %d Condition signal received. count = %d \n",*my_id,count); 
  }

  pthread_mutex_unlock(&count_mutex); 
  pthread_exit(NULL); 
} 
 
int main (int argc, char *argv[]) 
{ 
  int i, rc; 
  pthread_t threads[3]; 
  pthread_attr_t attr; 
 
  /* Initialize mutex and condition variable objects */ 
  pthread_mutex_init(&count_mutex, NULL); 
  pthread_cond_init (&count_threshold_cv, NULL); 
 
  /* For portability, explicitly create threads in a joinable state */ 
  pthread_attr_init(&attr); 
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
  pthread_create(&threads[0], &attr, inc_count, (void *)&thread_ids[0]); 
  pthread_create(&threads[1], &attr, inc_count, (void *)&thread_ids[1]); 
  pthread_create(&threads[2], &attr, watch_count, (void *)&thread_ids[2]); 
 
  /* Wait for all threads to complete */ 
  for (i=0; i<NUM_THREADS; i++) { 
    pthread_join(threads[i], NULL); 
  } 
  printf ("Main(): Waited on %d  threads. Done.\n", NUM_THREADS); 
 
  /* Clean up and exit */ 
  pthread_attr_destroy(&attr); 
  pthread_mutex_destroy(&count_mutex); 
  pthread_cond_destroy(&count_threshold_cv); 
  pthread_exit(NULL); 
 
} 

 

二、参考https://blog.youkuaiyun.com/hyp1977/article/details/51505744

所有的线程都是平级的,根本不存在主线程和子线程。下文所述为了方便,将在main函数中的线程看做主线程,其它线程看成子线程,特此说明。先考虑以下代码:


#include <pthread.h>
#include <stdio.h>
#include <unistd.h> 
void* thrd_start_routine(void* v)
{
    sleep(10);
        printf("created thread\n");
}

int main()
{
        pthread_t thrdid;
        pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);
        sleep(5);
        printf("main thread\n");        
        return  0;
}

运行,结果是5s休眠后,打印“main thread";程序退出

之前误认为线程和进程一样,主线程退出,子线程退出。再考虑以下代码:


#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

void* thrd_start_routine(void* v)
{
    sleep(10);
        printf("created thread\n");
}

int main()
{        pthread_t thrdid;

        pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);

        sleep(5);
        printf("main thread\n");
        pthread_exit(NULL);  
        printf("main exit\n");      
        return  0;
}

结果输出 main thread ;5s后输出 created thread;注意u,此处的main exit并不输出

相较于上一个程序,只加了一句 pthread_exit(NULL);

原因:

之前一个程序是在打印主线程之后,程序return,间接调用了exit()函数,因为一个线程调用exit函数,导致整个进程的退出,系统回收所有的资源,当然所有 的线程都退出了。

在主线程退出时,要想系统并不回收进程的所有资源,可以调用pthread_exit();然后等其他线程终止退出。

 

进程Process相关:

       程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。 IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC。

https://blog.youkuaiyun.com/wh_sjc/article/details/70283843

 

 

 

  
  
  
  
 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值