Thread concurrency - lock (ultra simple)

  1. Lock (mutex lock)

        What is a mutual exclusion lock? Let me give you an example. We can imagine it as a seat at a station, and then compare a thread to a person. Go down (indicating that you are using it), so that other people (other threads) can no longer use this seat. If you want to use this seat, you need to stand up so that others can use it.

Concurrent: happening at the same time

      In life, there may be multiple execution units accessing the same resource at the same time. Like seats. Use locks (mutexes) to protect resources

Mutex: A time value that allows an execution unit to access a shared resource

1. Define and initialize a lock

pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;

2. Before accessing shared resources

pthread_mutex_lock(pthread_mutex_t *mutex);

This function, if it finds that the lock is open, closes the lock directly, and then continues to execute....

If it is found that the lock is closed, this function will block/sleep the thread, waiting for others to unlock and wake up........... .

Until the other party unlocks the lock....acquires the lock, closes the lock..accesses...

3. Unlock after access

pthread_mutex_unlock(pthread_mutex_t *mutex);

May go to wake up the waiting thread........

Implementation code: 

#include <stdio.h>

#include <string.h>

#include <pthread.h>

#include <unistd.h>



struct msg_struct {

int aa;

int bb;

char des[32];

};



pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;

struct msg_struct data;


void *thread_write(void *argc)

{

int m=1;

while(1){


pthread_mutex_lock(&mylock);
m++;
data.aa=m*11;usleep(1000*1000); 
data.bb=m*111; usleep(1000*1000); 

//if(发现错误){  pthread_exit(); }   结果是没有解锁,然后 对方会被卡死.

strcpy(data.des,"hello,I am writer");
pthread_mutex_unlock(&mylock);
usleep(1000*300);
}
return NULL;

}

void *thread_read(void *argc)

{

while(1){

pthread_mutex_lock(&mylock);

printf("read aa=%d  bb=%d\n",data.aa,data.bb);

pthread_mutex_unlock(&mylock);

usleep(300);

}

return NULL;

}

int main(int argc,char **argv)

{

pthread_t rtid,wtid;

pthread_create(&wtid,NULL,thread_write,NULL );

pthread_detach(wtid);

pthread_create(&rtid,NULL,thread_read,NULL );

pthread_detach(rtid);



while(1){

printf("I am main thread\n");

sleep(5);

}

return 0;

}

Two, deadlock

1. A thread forgets to unlock after locking, and another thread is stuck.

2. If you need to access multiple shared resources at the same time, you need to acquire multiple locks at the same time.

        See the picture, the solution: all execution units must be accessed sequentially

3. Thread condition variable: thread notification 

        Sometimes a thread needs to wait for the arrival of a certain event/data, then process it, and continue waiting after the process is completed. Threads are divided into submitters and consumers

1. Consumer thread

while(1){

        In ##designated position##sleep waiting for data (waiting to be woken up) xx_wait()

        Data processing

}

2. Submitter thread

while(1){

        submit data

        To send a notification, go to ##designated location## to wake up xx_signal();

}

Implementation code:

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

struct msg_struct {

int val1;

int val2;

int result;

char des[32];

};


int data_flags =0 ; //0-无数据  1-有数据

struct msg_struct data;


pthread_mutex_t mutex_cond; //保护条件变量的锁, 因为两个线程可能同时访问它,造成并发问题

pthread_cond_t wait_cond; //等待者线程在这里睡眠, 提交者线程去这里唤醒睡眠的线程

// 床

void *wait_thread_fun(void *args)

{

while(1){


    if(data_flags == 0){


/*

睡眠等待被唤醒,线程卡死这里

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

cond,线程在 cond这里睡眠,等待被唤醒.

*/


pthread_mutex_lock(&mutex_cond);

pthread_cond_wait(&wait_cond,&mutex_cond );


/*

wait线程持有了锁,然后 去睡眠去了...... 问题来了,submit线程这时候就会被卡住.....

pthread_cond_wait()

{

    ...要去睡眠了,睡眠之前...释放锁...
    
    睡眠中.....,等待被唤醒..

    ----被唤醒...,  再次上锁..

}
*/




/*线程已经被唤醒了....*/

pthread_mutex_unlock(&mutex_cond);

}

data.result = data.val1+data.val2;

printf("wait thread got val1=%d val2=%d,result=%d\n",\

data.val1,data.val2,data.result);



data_flags = 0; //表示我已经处理完毕了数据.....

}

return NULL;

}


void *submit_thread_fun(void *args)

{

int m=234;

while(1){

sleep(3);

m+=10;

data.val1 = m*10;

data.val2 = m+111;

data_flags = 1;

/*

去指定位置 唤醒所有等待的 线程



int pthread_cond_signal(pthread_cond_t *cond);

cond: 条件变量, 等待者线程 在这里睡眠, 提交者线程去这里唤醒睡眠的线程.

返回值: 0-success, 失败 错误码

*/

pthread_mutex_lock(&mutex_cond);

int ret = pthread_cond_signal(&wait_cond);

pthread_mutex_unlock(&mutex_cond);

    if(ret){

    printf("signal err %s\n",strerror(ret)  );

    return NULL;

    }

}

return NULL;

}

int main(void)

{

pthread_t wait_tid;

pthread_t submit_tid;

pthread_create(&wait_tid, NULL,wait_thread_fun,NULL);

pthread_create(&submit_tid, NULL,submit_thread_fun,NULL);

pthread_detach(wait_tid  );

pthread_detach(submit_tid);


while(1){

    printf("I am main \n");

    sleep(5);

    }

return 0;

}

Guess you like

Origin blog.csdn.net/qq_53676406/article/details/129148295