[Top] linux process and thread comparison thread wins in development

threads and processes

This concept is the same no matter what operating system is used, and it is also what interviewers like to ask. It represents your knowledge of program optimization. When working on Android, it is often used to optimize processing speed and data processing, combined with handler. Handle and solve the problem that the interface is often dead.

Now that we have concluded, this time we will fully summarize:

process

Process composition:

  1. Process Control Block PCB
  2. block
  3. data segment

The process control block PCB is a PCB area stored in the kernel. It is a record data structure. The PCB records the parameters required by the operating system and is used to describe the current situation of the process and all the information about the operation of the process, including

  1. Process description information:
    1. process identifier, identifying the process
    2. User ID for resource sharing and protection
    3. Family relationship, process information about having parent and child processes
  2. Processor state information: including general registers, instruction registers, program status word (PSW), user stack pointer, etc.
    1. Process status, used as a basis for process scheduling
    2. The priority of the process, the basis for the processor to run the process
    3. Data required for process scheduling: such as the sum of the CPUs that have been waiting, the sum of the time the process has executed
    4. Event: The reason the process is blocked
  3. process control information
    1. Program and data addresses
    2. Processes and Synchronous Communication Mechanisms

The state of the process: ready, executing, blocked

process

The above are the various state switches of the process

When the process is first initialized, the process enters the ready state and waits for the OS to allocate the processor to process the process. When the process obtains the processor to process, the process executes, and executes, it is generally used to process various things, such as requesting IO processing, etc. , but once there is a lot of IO processing, it is easy to enter the blocking state. At this time, we often see the state where the computer is stuck, but after processing, the process will enter the ready state.
In fact, there is another state, the finish end state, but as long as the process dies just quit

thread

It is easy to see from the above that to create a process, because it directly processes data with the linux kernel, a large number of parameters need to be provided to ensure the safety, efficiency and stability of the process, and consume a lot of system resources, but the thread is different, the principle is In the same way, as a lightweight, it consumes very little system resources, and as a developer, threads are easier and more convenient to use, and threads can only run in the process, so the data that interacts with the system kernel is handed over to the process. Now, the thread is simple and easy to use. It is said that the process consumes 30 times the resources of the thread...
Thread and processing flow and process are not bad, and they are also in four states: ready, executing, blocking, and ending.

API for multithreaded programming

create thread

int pthread_create(pthread_t *thread,pthread_attr_t *attr,void * (*func)(void * ),void *arg);
/*
看了上面的方法,mmp、wtf 这些词汇从我脑海中冒出来,函数参数要不要写的那么复杂
只能看调用示例了:
pthread(&thrd1,NULL,(void*)task1,(void*)&g1);
phtread thrd1 表示创建线程的标识
pthread_attr_t *attr 表示线程属性NULL 默认
void task1 线程需要执行的代码
int g1 表示task1的参数
*/

end thread

pthread_exit(void *retval);
//retval 用来存放自杀线程退出状态

wait for thread to end

// 多个线程启动后,由系统负责调度,但我们并不知道哪个会先开始和结束,只能等待
int pthread_join(pthread_t th,void **thread_return);
/*
th 等待线程的标识
thread_return 返回的状态
*/

Example of multithreading:

In the case of only synchronization locks, synchronization between threads is mutually exclusive

Use the principle of synchronization and mutual exclusion to realize the operation of the variable shareid

int shareid=0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int main(int argc, char const *argv[]) {
  pthread_t thrd1,thrd2;
  int ret;
  ret = pthread_create(&thrd1,NULL,(void *)task1,NULL);//创建线程
  ret = pthread_create(&thrd2,NULL,(void *)task2,NULL);
  pthread_join(thrd1,NULL);//等待线程结束
  pthread_join(thrd2,NULL);
  printf("shareid = %d\n",shareid );
  return 0;
}
  void task1(void) {
    long i,tmp;
    for ( i = 0; i < 10000; i++) {
      if (pthread_mutex_lock(&mutex)!=0) {//加同步锁
        perror("pthread_mutex_lock");
          exit(EXIT_FAILURE);
      }
      tmp = shareid;
      tmp = tmp+1;
      shareid = tmp;
      if (pthread_mutex_unlock(&mutex)!=0) {//解锁
        perror("pthread_mutex_unlock");
        exit(EXIT_FAILURE);
      }
    }
    printf("task1 finished shareid = %d\n" ,shareid);
  }
  void task2(void) {
    long i,tmp;
    for ( i = 0; i < 5000; i++) {
      if (pthread_mutex_lock(&mutex)!=0) {
        perror("pthread_mutex_lock");
          exit(EXIT_FAILURE);
      }
      tmp = shareid;
      tmp = tmp+1;
      shareid = tmp;
      if (pthread_mutex_unlock(&mutex)!=0) {
        perror("pthread_mutex_unlock");
        exit(EXIT_FAILURE);
      }
    }
    printf("task2 finished shareid = %d\n" ,shareid);
  }

Because pthread is not a standard library compiled by gcc, you need to use dynamic library loading, and add -lpthread at the end of the compilation command.

gcc pthread_create.c -o pthread_create -lpthread

debug result:

ph_create

Thread + synchronization lock + semaphore will be more interesting

Obviously, the synchronization lock is a bit rigid. It can only operate one variable at a time, and cannot realize the operation of multiple public resources, but it is interesting to add a semaphore.

Introducing the semaphore API

Create a semaphore

#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int value);
/*
功能: 初始化 信号量
返回值: 成功返回0 错误返回-1
sem: 指向信号量结构的指针
pshared 不为0 信号量在进程间共享,不然只能在本进程中的所有线程中共享
value 给出信号量的初始值
*/

Semaphore P operation -1

int sem_wait(sem_t *sem);

Semaphore V operation +1

int sem_post(sem_t *sem);

Semaphore deletion

int sem_destroy(sem_t *sem);

After reading the above API, is it different from the API used in the process? linux ipc inter-process communication summary
I can only understand this way, different semaphore APIs apply to processes and threads

The case is as follows:

# define MAXSIZE 10

int stack[MAXSIZE][2];
int size = 0;
sem_t sem;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void provide_data(void){

  int i;
  for (i = 0; i < MAXSIZE; i++) {
    stack[i][0] = i;
    stack[i][1] = i;
    sem_post(&sem);// 信号量 V操作 +1
  }
}


void handle_data1(void) {
  int i;
  while (pthread_mutex_lock(&mutex),((i =size++)<MAXSIZE)) {
    pthread_mutex_unlock(&mutex);
    sem_wait(&sem);
    printf("Plus : %d + %d =%d \n",stack[i][0],stack[i][1],stack[i][0]+stack[i][1] );
  }
  pthread_mutex_unlock(&mutex);
}

void handle_data2(void) {
  int i;
  while (pthread_mutex_lock(&mutex),((i =size++)<MAXSIZE)) {
    pthread_mutex_unlock(&mutex);
    sem_wait(&sem);
    printf("Multiple : %d × %d =%d \n",stack[i][0],stack[i][1],stack[i][0]*stack[i][1] );
  }
  pthread_mutex_unlock(&mutex);
}

int main(int argc, char const *argv[]) {
  pthread_t thd1,thd2,thd3;
  sem_init(&sem,0,0);
  pthread_create(&thd1,NULL,(void *)handle_data1,NULL);
  pthread_create(&thd2,NULL,(void *)handle_data2,NULL);
  pthread_create(&thd3,NULL,(void *)provide_data,NULL);

  pthread_join(thd1,NULL);
  pthread_join(thd2,NULL);
  pthread_join(thd3,NULL);
  sem_destroy(&sem);
  return 0;
}

There is a thread th3 that assigns a value to the stack loop, and operates the semaphore sem V every time it is assigned. The two threads, thd1 and thd2, will compete to obtain the stack. The operation thd1 is a summation, and thd2 is a quotient. Which thread obtains the resource? Sum or quotient, and then operate on the sem process P, so each time the program is run, different results will be printed.
write picture description here
Here is another knowledge point, the comma operator

  while (pthread_mutex_lock(&mutex),((i =size++)<MAXSIZE)) {
    pthread_mutex_unlock(&mutex);
/*
 while 有两个表达式,最后只判断((i =size++) <MAXSIZE) 是否符合,前面只是对mutex 进行加锁操作,这样只是为了保证size 能正常执行++操作和判断
 */

Comma expression: both expressions before and after the comma are executed, but only the last return value is valid

Other unbelieve knowledge points

The second parameter above pthread_create has always set the NULL system default attribute, but if we set it, how to set it?

If you set thread attributes, you must use pthread_attr_init before pthread_create . The

pthread_attr_t structure contains whether to bind, whether to separate, stack address, stack size, and priority information.

The default attribute is non-binding, non-detaching, and the default 1M size. The stack priority is the same as the process.

The concept of light process is understood as a kernel process, which is located between the user layer and the system layer. The system allocates thread resources through the light process. If the setting is bound to the light process, the thread has high responsiveness.

binding state

Function pthread_attr_setscope

to set binding state binding: PTHREAD_SCOPE_SYSTEM unbound PTHREAD_SCOPE_PROCESS

separation state

The detached state of the thread is used to decide how to end itself. The
non- detached state is processed by pthread_join

to release resources. The thread in the detached state is automatically released after running. Non-detached: PTHREAD_CREATE_JOINABLE.

If the thread separation state is set, the thread runs too fast, after pthread_attr_init, but before pthread_create, then creating a thread at this time will get the wrong thread number, which needs to be avoided. The easiest way is to execute pthread_cond_timewait to make the thread run slower

thread priority

The thread priority is stored in the structure sched_param and stored with the pthread_attr_getsparam function and pthread_attr_setschedpara , first obtain the priority, modify it, and store it back

Change properties after thread creation:

Method to kill other threads pthread_cancel (thread)

But the thread can set the property to refuse to be killed

pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL)

The thread is really good, and there are many optimizations


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324517666&siteId=291194637