[Linux] multi-threaded scenarios practice

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/bible_reader/article/details/95053607

Multi-threaded scenarios practice

scene 1

There are four threads 1,2,3,4. Thread 1 is the function of output 1, 2 thread function is to output 2, and so on ......... now have four files ABCD. Initial are empty. Now let four documents were the following format:

A:1 2 3 4 1 2....

B:2 3 4 1 2 3....

C:3 4 1 2 3 4....

D:4 1 2 3 4 1....
 

Code:

#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
#include <fstream>

using namespace std;

#define num_threads     4

pthread_cond_t ready = pthread_cond_initializer;  // 线程ready
pthread_mutex_t mutex = pthread_mutex_initializer;  // 条件变量ready的互斥锁
pthread_mutex_t c_mutex = pthread_mutex_initializer;  // 为了保险,将sequence的访问也加上互斥锁

int state = 1; // 全局进程状态ready标记,1 表示线程1ready,2 表示线程2 ready,3 表示线程3 ready,4表示线程4 ready
int sequence[] = {1, 2, 3, 4}; // 初始的文件内容的写入顺序,后期每一次操作4个文件,便重新利用函数constructwritesequence() 构建一次sequence

string files[] = {
    "filea.txt", "fileb.txt", "filec.txt", "filed.txt"
}; //  文件列表,后期不同的线程执行的时候,按照sequence去写入对应的文件

void writedata(int i);

void constructwritesequence(int sequence[], int filenum)
{
    pthread_mutex_lock(&c_mutex);
    int temp = sequence[0];;
    int i = 1;
    for (; i < filenum; i++)
    {
        sequence[i - 1] = sequence[i];
    }
    sequence[i - 1] = temp;
    // cout << "next file process sequcece is: " << endl;
    for (i = 0; i < filenum; i++)
    {
        cout << sequence[i] << " ";
    }
    cout <<endl;
    pthread_mutex_unlock(&c_mutex);
}

void printer(int thread_id)
{
    for (int i = 0; i < 4; i++)
    {
        if ((i + 1) == thread_id)
            // cout << i;
            writedata(i + 1);
    }
}

int getindex(int i)
{
    for (int index = 0; index < sizeof(sequence)/sizeof(int); index++)
    {
        if (i == sequence[index])
            return index;
    }
    return 0x1234;
}

void writedata(int i)
{
    pthread_mutex_lock(&c_mutex);
    std::fstream afile;
    int index = getindex(i);
    if (index == 0x1234) {
         cout << "index is out of bound" << endl;
         return;
    }
    cout << "index is " << index << "i is " << i << endl;
    afile.open(files[index].c_str(), std::ios::app | std::ios::out | std::ios::in);
    afile << i << " ";

    afile.close();
    pthread_mutex_unlock(&c_mutex);
}

void* printer(void* arg)
{
    int thread_id = *(int* )arg;
    for(int index = 0; index < 10; index++) {  // 演示 10 轮
        pthread_mutex_lock(&mutex);
        while (thread_id % 4 != state) {
            pthread_cond_wait(&ready, &mutex); // 如果thread_id % 4 != state,则对应的线程需要继续等待ready条件满足
        }
        printer(thread_id);
        state = (state + 1) % 4;  // 修改对应的线程ready标记
        if (thread_id == 4) {
            constructwritesequence(sequence, 4);
        }
        pthread_mutex_unlock(&mutex);
        pthread_cond_broadcast(&ready);  // 某一个线程打印完毕后,设置state值,并通知其他所有线程,其他所有线程按照state的值,检查是否自己等待的ready条件是否满足
    }

    pthread_exit((void*) 1);  // 每一个线程的返回值设置为1;
}

int main ()
{
   int rc;
   int i;
   int thread_ids[] = {1, 2, 3, 4};
   pthread_t threads[num_threads];
   pthread_attr_t attr;
   void *status;


   // 初始化并设置线程为可连接的(joinable)
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, pthread_create_joinable);

   // 创建4个线程
   for( i=0; i < num_threads; i++ ){
      rc = pthread_create(&threads[i], null, printer, (void*)(thread_ids + i));
      if (rc){
         cout << "create thread falied: " << rc << endl;
         exit(-1);
      }
   }


   // 删除属性,并等待其他线程
   pthread_attr_destroy(&attr);
   for( i=0; i < num_threads; i++ ){
      rc = pthread_join(threads[i], &status);
      if (rc){
         cout << "error:unable to join," << rc << endl;
         exit(-1);
      }
      cout << endl;
      cout << "main: completed thread id :" << i ;
      cout << "  exiting with status :" << status << endl;
   }

   cout << "main: program exiting." << endl;
   pthread_exit(null);
}
                          

 

Guess you like

Origin blog.csdn.net/bible_reader/article/details/95053607