问:
Why isn't my global allocation structure updating values correctly?
I've been working on a bankers algorithm implementation in C and it seems to work fine except the allocation matrix isn't adding values correctly. In the request resources function, I use a mutex lock at the beginning and unlock right before returning a value to indicate pass or failure. In the function itself, the allocation matrix updates with what's been requested and given but when another thread comes in and does it's request, the allocation resets and starts adding again. I'm not sure why this is since allocation is global like the other structures being modified in the function and they are updating values properly.</p>

```<code>    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<pthread.h>
    #include<semaphore.h>

    /* these may be any values >= 0 */

    #define NUMBER_OF_CUSTOMERS 5
    #define NUMBER_OF_RESOURCES 3

    /* the available amount of each resource */
    int available[NUMBER_OF_RESOURCES];

    /*the maximum demand of each customer */
    int maximum[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];

    /* the amount currently allocated to each customer */
    int allocation[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];

    /* the remaining need of each customer */
    int need[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];

    pthread_mutex_t mutex =
    PTHREAD_MUTEX_INITIALIZER;

    struct threadParams {
        int req[3];
        int threadNum;
    };

        int safe_state(int customer_num){

            int work[NUMBER_OF_RESOURCES];
            int done =0;
            for(int w = 0; w < NUMBER_OF_CUSTOMERS; w++){
                work[w] = available[w];
            }

            int finish[NUMBER_OF_CUSTOMERS];

            for(int i = 0; i < NUMBER_OF_CUSTOMERS; i++){
                finish[i] = 0;
                //setting finish to false
            }

            for(int k = 0; k < NUMBER_OF_CUSTOMERS; k++){
                for(int j = 0; j< NUMBER_OF_RESOURCES; j++){
                    if(finish[k] == 0 && need[customer_num][k] <= work[j]){
                        work[j] += allocation[customer_num][j];
                        finish[k] = 1;
                        //printf("%d\n", finish[k]);
                    }
                }
            }

            for(int x = 0; x < NUMBER_OF_CUSTOMERS; x++){
                if(finish[x] == 1){
                    done = 1;
                }
                else{
                    done = -1;
                }
            }
            if(done == 1){
                printf("\n Granted\n");
                return done;
            }
            printf("\nDenied\n");
            return done;

        }

        void* request_resources(void *arg){
            pthread_mutex_lock(&mutex);
            struct threadParams  *params = arg;
            int customer_num = params->threadNum;
            printf("\nCustomer %d is in critical\n", customer_num+1);
            int request[3];
            request[0] = params->req[0];
            request[1] = params->req[1];
            request[2] = params->req[2];

            int pass;
            for(int i = 0; i < NUMBER_OF_RESOURCES; i++){
                if(request[i] <= need[customer_num][i] && request[i] <= available[i]){
                    //printf("\nreq: %d, need: %d, avail: %d, alloc: %d\n\t", request[i], need[customer_num][i], available[i],allocation[customer_num][i]);
                    int state = safe_state(customer_num);

                    if(state == 1){
                        available[i] -= request[i];
                        allocation[customer_num][i] += request[i];
                        //printf("%d + %d\n", allocation[customer_num][i], request[i]);
                        need[customer_num][i] -= request[i];
                        pass = 1;

                    }
                    else if(state == -1){
                        printf("\nThe request from customer %d results in unsafe state\n", customer_num+1);
                        printf("\nreq: %d, need: %d, avail: %d, alloc: %d\n\t", request[i], need[customer_num][i], available[i],allocation[customer_num][i]);
                        pass = -1;
                        break;
                    }
                }
                else{
                    printf("\nreq: %d, need: %d, avail: %d\n", request[i], need[customer_num][i], available[i]);
                    printf("\nNot enough resources for customer %d's request or the customer doesn't need this resource.\n", customer_num);
                    pass = -1;
                    break;
                }
                printf("\nResource: %d req: %d, need: %d, avail: %d, alloc: %d\n\t",i+1, request[i], need[customer_num][i], available[i],allocation[customer_num][i]);

            }
            //printf("I'm a thread\n");
            pthread_mutex_unlock(&mutex);
            printf("\n Customer %d has left critical\n", customer_num+1);
            return pass;

        }

        int release_resources(int customer_num, int release[]){

        }

    int main(int argc, char *argv[]){
        pthread_t threads [NUMBER_OF_CUSTOMERS];
        int result;
        unsigned index = 0;

        // for(int ii = 0; ii < NUMBER_OF_CUSTOMERS; ii++){
            // for(int jj = 0; jj < NUMBER_OF_RESOURCES; jj++){
                // allocation[ii][jj] += 0;
            // }
        // }

        for(index = 0; index < NUMBER_OF_RESOURCES; index++){
            available[index] = strtol(argv[index+1], NULL,10);
        }

        for(int i = 0; i < NUMBER_OF_CUSTOMERS; i++){
            for(int j = 0; j < NUMBER_OF_RESOURCES; j++){
            maximum[i][j] = strtol(argv[j+1], NULL, 10)-4;
            need[i][j] = 2; //strtol(argv[j+1], NULL, 10) - 6;
            //printf("%d\t", maximum[i][j]);
            }
        }

        for(index = 0; index < NUMBER_OF_CUSTOMERS; index++){
            printf("\nCreating customer %d\n", index+1);
            struct threadParams params;
            params.req[0] = 2;
            params.req[1] = 2;
            params.req[2] = 2;
            params.threadNum = index;
            result = pthread_create(&threads[index],NULL,request_resources,&params);

        }

        for(index = 0; index < NUMBER_OF_CUSTOMERS; ++index){
            pthread_join(threads[index], NULL);
        }

        printf("\nDone");

    }
</code>```

答:
Finally, I found some time to handle this seriously:

I still have problems to understand your implementation in general. (I spent some hours to first understand Edsger Dijkstras Banker's algorithm itself before I came back.)

Thus, I do not understand why you distinguish need[] and threadParams.req[]. When I got it right this should actually be the same (i.e. one of them should not be there).

However, I want to show you what I got so far (which might be a help). After I studied and compared multiple samples I finally made a modified version of Banker's Algorithm on rosettacode.org:

```<code>#ifdef __cplusplus
#include <cassert>
#include <cstdio>
#include <cstring>
using namespace std;
#else /* (not) __cplusplus */
#include <assert.h>
#include <stdio.h>
#include <string.h>
#endif /* __cplusplus */

enum { nResources = 4 };
enum { nCustomers = 3 };

struct System {
  /* the total amount of resources */
  int total[nResources];
  /* the available amount of each resource */
  int available[nResources];
  /* currently allocated resources */
  int allocation[nCustomers][nResources];
  /* the maximum demand of each customer */
  int maximum[nCustomers][nResources];
};

static struct System testSetSafe1 = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 2, 2, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 3, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

static struct System testSetSafe2 = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 0, 0, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 5, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

static struct System testSetUnsafe = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 2, 2, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 5, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

void initSystem(struct System *pSystem)
{
  for (int j = 0; j < nResources; ++j) {
    pSystem->available[j] = pSystem->total[j];
    for (int i = 0; i < nCustomers; ++i) {
      pSystem->available[j] -= pSystem->allocation[i][j];
    }
  }
}

void printR(const char *title, int table[nResources])
{
  printf("%s:\n", title);
  for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
  printf("\n");
  for (int j = 0; j < nResources; ++j) printf("\t%d", table[j]);
  printf("\n");
}

void printCR(const char *title, int table[nCustomers][nResources])
{
  printf("%s:\n", title);
  for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
  printf("\n");
  for (int i = 0; i < nCustomers; ++i) {
    printf("C%d", i + 1);
    for (int j = 0; j < nResources; ++j) printf("\t%d", table[i][j]);
    printf("\n");
  }
}

int run(struct System *pSystem)
{
  initSystem(pSystem);
  printR("Total resources in system", pSystem->total);
  printR("Available resources", pSystem->available);
  printCR("Customers (currently allocated resources)",
    pSystem->allocation);
  printCR("Customers (maximum required resources", pSystem->maximum);
  int running[nCustomers];
  for (int count = nCustomers, safe; count;) {
    safe = 0;
    for (int i = 0; i < nCustomers; ++i) {
      if (running[i]) {
        int needed[nResources], blocked = 0;
        for (int j = 0, block; j < nResources; ++j) {
          needed[j]
            = pSystem->maximum[i][j] - pSystem->allocation[i][j];
          if ((block = needed[j] > pSystem->available[j])) {
            printf("Customer %d blocked due to resource %c\n",
              i + 1, 'A' + j);
          }
          blocked |= block;
        }
        if (!blocked) {
          printf("Customer %d is served.\n", i + 1);
          /* allocate resources */
          for (int j = 0; j < nResources; ++j) {
            pSystem->available[j] -= needed[j];
            pSystem->allocation[i][j] += needed[j];
            assert(pSystem->allocation[i][j] == pSystem->maximum[i][j]);
          }
          /* perform customer */
          printR("Allocated resources", pSystem->allocation[i]);
          running[i] = 0;
          printf("Customer %d is done.\n", i + 1);
          --count; /* customer finished */
          safe = 1; /* processes still safe (no deadlock) */
          /* free resources */
          for (int j = 0; j < nResources; ++j) {
            pSystem->available[j] += pSystem->allocation[i][j];
            pSystem->allocation[i][j] = 0;
          }
          break; /* bail out of inner loop */
        }
      }
    }
    if (!safe) {
      printf("Unsafe state (i.e. dead lock).\n");
      printR("Total resources in system", pSystem->total);
      printR("Available resources", pSystem->available);
      printCR("Customers (currently allocated resources)",
        pSystem->allocation);
      printCR("Customers (maximum required resources",
        pSystem->maximum);
      return -1;
    }
    printR("Available resources", pSystem->available);
  }
  return 0;
}

int main()
{
  /* 1st try: all requests can be granted soon */
  printf(
    "1st Run:\n"
    "========\n"
    "\n");
  run(&testSetSafe1);
  printf("\n");
  /* 2nd try: all requests can be granted by changing order */
  printf("2nd Run:\n"
    "========\n"
    "\n");
  run(&testSetSafe2);
  printf("\n");
  /* 3rd try: unsafe state */
  printf("3rd Run:\n"
    "========\n"
    "\n");
  run(&testSetUnsafe);
  printf("\n");
  /* done */
  printf("Done.\n");
  return 0;
}
</code>```

(Debugged in VS2013 but) compiled and tested with gcc in cygwin on Windows 10 (64 bit):

```<code>$ gcc -std=c11 -x c bankers.cc -o bankers

$ ./bankers
1st Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      3       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Customer 1 is served.
Allocated resources:
        A       B       C       D
        3       3       2       2
Customer 1 is done.
Available resources:
        A       B       C       D
        4       3       3       3
Customer 2 is served.
Allocated resources:
        A       B       C       D
        1       2       3       4
Customer 2 is done.
Available resources:
        A       B       C       D
        5       3       6       6
Customer 3 is served.
Allocated resources:
        A       B       C       D
        1       3       5       0
Customer 3 is done.
Available resources:
        A       B       C       D
        6       5       7       6

2nd Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       3       3       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       0       0       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Customer 1 blocked due to resource A
Customer 2 is served.
Allocated resources:
        A       B       C       D
        1       2       3       4
Customer 2 is done.
Available resources:
        A       B       C       D
        4       3       6       5
Customer 1 is served.
Allocated resources:
        A       B       C       D
        5       3       2       2
Customer 1 is done.
Available resources:
        A       B       C       D
        5       3       6       6
Customer 3 is served.
Allocated resources:
        A       B       C       D
        1       3       5       0
Customer 3 is done.
Available resources:
        A       B       C       D
        6       5       7       6

3rd Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Customer 1 blocked due to resource A
Customer 2 blocked due to resource B
Customer 3 blocked due to resource C
Unsafe state (i.e. dead lock).
Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0

Done.

$
</code>```

This looks quite good (for me).

Now, I made a derived sample introducing multi-threading.

A note about this:

The Wikipedia article Banker's algorithm states that the algorithm is intended for OS resource management like e.g. memory, semaphores and interface access. Sounds for me like, these algorithm is intended to manage things like muteces. Thus, a mutex should/can not be used for it and multi-threading makes not so much sense.

However, let forget about my concern and say this is for educational/understanding purpose:

```<code>#ifdef __cplusplus
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <mutex>
#include <thread>
using namespace std;
#else /* (not) __cplusplus */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#endif /* __cplusplus */

enum { nResources = 4 };
enum { nCustomers = 3 };

struct System {
  /* the total amount of resources */
  int total[nResources];
  /* the available amount of each resource */
  int available[nResources];
  /* currently allocated resources */
  int allocation[nCustomers][nResources];
  /* the maximum demand of each customer */
  int maximum[nCustomers][nResources];
  /* customers to serve, blocked customers */
  int running, blocked;
};

static struct System testSetSafe1 = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 2, 2, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 3, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

static struct System testSetSafe2 = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 0, 0, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 5, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

static struct System testSetUnsafe = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 2, 2, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 5, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

void initSystem(struct System *pSystem)
{
  for (int j = 0; j < nResources; ++j) {
    pSystem->available[j] = pSystem->total[j];
    for (int i = 0; i < nCustomers; ++i) {
      pSystem->available[j] -= pSystem->allocation[i][j];
    }
  }
  pSystem->running = nCustomers; pSystem->blocked = 0;
}

void printR(const char *title, int table[nResources])
{
  printf("%s:\n", title);
  for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
  printf("\n");
  for (int j = 0; j < nResources; ++j) printf("\t%d", table[j]);
  printf("\n");
}

void printCR(const char *title, int table[nCustomers][nResources])
{
  printf("%s:\n", title);
  for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
  printf("\n");
  for (int i = 0; i < nCustomers; ++i) {
    printf("C%d", i + 1);
    for (int j = 0; j < nResources; ++j) printf("\t%d", table[i][j]);
    printf("\n");
  }
}

struct Customer {
  int i;
  struct System *pSystem;
  int blocked;
};

static void initCustomer(
  struct Customer *pCustomer, int i, struct System *pSystem)
{
  pCustomer->i = i;
  pCustomer->pSystem = pSystem;
  pCustomer->blocked = 0;
}

#ifdef __cplusplus
/* multi-threading thin layer for C++ and std::thread */
static mutex mtx;
static inline void lockMutex(mutex *pMtx) { pMtx->lock(); }
static inline void unlockMutex(mutex *pMtx) { pMtx->unlock(); }
typedef std::thread Thread;
static inline int startThread(
  Thread *pThread,
  void* (*pThreadFunc)(Customer*), Customer *pCustomer)
{
  return (*pThread = Thread(pThreadFunc, pCustomer)).get_id()
    == Thread::id();
  /* thread creation failed -> thread id == thread::id() -> 1
   * thread creation successful -> thread id != thread::id() -> 0
   */
}
static inline void joinThread(Thread *pThread) { pThread->join(); }
#else /* (not) __cplusplus */
/* multi-threading thin layer for C and pthread */
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static void lockMutex(pthread_mutex_t *pMtx)
{
  pthread_mutex_lock(pMtx);
}
static void unlockMutex(pthread_mutex_t *pMtx)
{
  pthread_mutex_unlock(pMtx);
}
typedef pthread_t Thread;
static int startThread(
  Thread *pThread,
  void* (*pThreadFunc)(struct Customer*),
  struct Customer *pCustomer)
{
  return pthread_create(pThread, NULL,
    (void*(*)(void*))pThreadFunc, pCustomer);
}
static void joinThread(Thread *pThread) { pthread_join(*pThread, NULL); }
#endif /* __cplusplus */

void* runCustomer(struct Customer *pCustomer)
{
  int i = pCustomer->i;
  struct System *pSystem = pCustomer->pSystem;
  int needed[nResources];
  for (int j = 0; j < nResources; ++j) {
    needed[j] = pSystem->maximum[i][j] - pSystem->allocation[i][j];
  }
  for (int done = 0; !done;) {
    lockMutex(&mtx); /* thread-safe access to shared system */
    if (pCustomer->blocked) --pSystem->blocked;
    pCustomer->blocked = 0;
    for (int j = 0, block; j < nResources; ++j) {
      if ((block = needed[j] > pSystem->available[j])) {
        printf("Customer %d blocked due to resource %c\n",
          i + 1, 'A' + j);
      }
      pCustomer->blocked |= block;
    }
    if (!pCustomer->blocked) {
      printf("Customer %d is served.\n", i + 1);
      /* allocate resources */
      for (int j = 0; j < nResources; ++j) {
        pSystem->available[j] -= needed[j];
        pSystem->allocation[i][j] += needed[j];
        assert(pSystem->allocation[i][j] == pSystem->maximum[i][j]);
      }
      /* perform customer */
      printR("Allocated resources", pSystem->allocation[i]);
      --pSystem->running;
      done = 1; /* customer finished */
      printf("Customer %d is done.\n", i + 1);
      /* free resources */
      for (int j = 0; j < nResources; ++j) {
        pSystem->available[j] += pSystem->allocation[i][j];
        pSystem->allocation[i][j] = 0;
      }
    } else {
      ++pSystem->blocked;
      if ((done = pSystem->running <= pSystem->blocked)) {
        printf("Customer %d exited (due to dead-lock).\n", i + 1);
      }
    }
    unlockMutex(&mtx);
  }
  return 0;
}

int run(struct System *pSystem)
{
  initSystem(pSystem);
  printR("Total resources in system", pSystem->total);
  printR("Available resources", pSystem->available);
  printCR("Customers (currently allocated resources)",
    pSystem->allocation);
  printCR("Customers (maximum required resources", pSystem->maximum);
  /* created threads for customers */
  lockMutex(&mtx); /* force concurrency a little bit */
  Thread threads[nCustomers];
  struct Customer customers[nCustomers];
  for (int i = 0; i < nCustomers; ++i) {
    printf("Creating customer %d\n", i + 1);
    initCustomer(customers + i, i, pSystem);
    if (startThread(threads + i, &runCustomer, customers + i)) {
      printf("ERROR: Failed to start thread for customer %d!\n", i + 1);
    }
  }
  /* unlock mutex to let threads compete */
  printf("Ready, steady, go...\n");
  unlockMutex(&mtx);
  /* join all threads */
  for (int i = 0; i < nCustomers; ++i) joinThread(threads + i);
  /* report */
  if (pSystem->blocked) {
    printf("Unsafe state (i.e. dead lock).\n");
    printR("Total resources in system", pSystem->total);
    printR("Available resources", pSystem->available);
    printCR("Customers (currently allocated resources)",
      pSystem->allocation);
    printCR("Customers (maximum required resources",
      pSystem->maximum);
    return -1;
  }
  return 0;
}

int main()
{
  /* 1st try: all requests can be granted soon */
  printf(
    "1st Run:\n"
    "========\n"
    "\n");
  run(&testSetSafe1);
  printf("\n");
  /* 2nd try: all requests can be granted by changing order */
  printf("2nd Run:\n"
    "========\n"
    "\n");
  run(&testSetSafe2);
  printf("\n");
  /* 3rd try: unsafe state */
  printf("3rd Run:\n"
    "========\n"
    "\n");
  run(&testSetUnsafe);
  printf("\n");
  /* done */
  printf("Done.\n");
  return 0;
}
</code>```

(Again debugged in VS2013 but) compiled and tested with gcc in cygwin on Windows 10 (64 bit):

```<code>$ gcc -std=c11 -x c bankersMT.cc -o bankersMT -pthread

$ ./bankersMT
1st Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      3       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Creating customer 1
Creating customer 2
Creating customer 3
Ready, steady, go...
Customer 1 is served.
Allocated resources:
        A       B       C       D
        3       3       2       2
Customer 1 is done.
Customer 2 is served.
Allocated resources:
        A       B       C       D
        1       2       3       4
Customer 2 is done.
Customer 3 is served.
Allocated resources:
        A       B       C       D
        1       3       5       0
Customer 3 is done.

2nd Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       3       3       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       0       0       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Creating customer 1
Creating customer 2
Creating customer 3
Ready, steady, go...
Customer 1 blocked due to resource A
Customer 2 is served.
Allocated resources:
        A       B       C       D
        1       2       3       4
Customer 2 is done.
Customer 3 is served.
Allocated resources:
        A       B       C       D
        1       3       5       0
Customer 3 is done.
Customer 1 is served.
Allocated resources:
        A       B       C       D
        5       3       2       2
Customer 1 is done.

3rd Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Creating customer 1
Creating customer 2
Creating customer 3
Ready, steady, go...
Customer 1 blocked due to resource A
Customer 2 blocked due to resource B
Customer 3 blocked due to resource C
Customer 3 exited (due to dead-lock).
Customer 1 blocked due to resource A
Customer 1 exited (due to dead-lock).
Customer 2 blocked due to resource B
Customer 2 exited (due to dead-lock).
Unsafe state (i.e. dead lock).
Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0

Done.

$
</code>```

Although, this looks quite good also, I'm not sure about whether the dead-lock detection is 100 % correct. Because multi-threading introduces non-deterministics, this is hard to test. I tried to "debug it by head" but ended up with headache...

Note about implementation:

I used the thin-layer for multi-threading, again. Thus, these samples can be compiled in C++ (std::thread, VS2013/g++) as well as in C (pthread, gcc).

Body:
I've been working on a bankers algorithm implementation in C and it seems to work fine except the allocation matrix isn't adding values correctly. In the request resources function, I use a mutex lock at the beginning and unlock right before returning a value to indicate pass or failure. In the function itself, the allocation matrix updates with what's been requested and given but when another thread comes in and does it's request, the allocation resets and starts adding again. I'm not sure why this is since allocation is global like the other structures being modified in the function and they are updating values properly.

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

    /* these may be any values >= 0 */

    #define NUMBER_OF_CUSTOMERS 5
    #define NUMBER_OF_RESOURCES 3

    /* the available amount of each resource */
    int available[NUMBER_OF_RESOURCES];

    /*the maximum demand of each customer */
    int maximum[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];

    /* the amount currently allocated to each customer */
    int allocation[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];

    /* the remaining need of each customer */
    int need[NUMBER_OF_CUSTOMERS][NUMBER_OF_RESOURCES];

    pthread_mutex_t mutex =
    PTHREAD_MUTEX_INITIALIZER;

    struct threadParams {
        int req[3];
        int threadNum;
    };

        int safe_state(int customer_num){

            int work[NUMBER_OF_RESOURCES];
            int done =0;
            for(int w = 0; w < NUMBER_OF_CUSTOMERS; w++){
                work[w] = available[w];
            }

            int finish[NUMBER_OF_CUSTOMERS];

            for(int i = 0; i < NUMBER_OF_CUSTOMERS; i++){
                finish[i] = 0;
                //setting finish to false
            }

            for(int k = 0; k < NUMBER_OF_CUSTOMERS; k++){
                for(int j = 0; j< NUMBER_OF_RESOURCES; j++){
                    if(finish[k] == 0 && need[customer_num][k] <= work[j]){
                        work[j] += allocation[customer_num][j];
                        finish[k] = 1;
                        //printf("%d\n", finish[k]);
                    }
                }
            }

            for(int x = 0; x < NUMBER_OF_CUSTOMERS; x++){
                if(finish[x] == 1){
                    done = 1;
                }
                else{
                    done = -1;
                }
            }
            if(done == 1){
                printf("\n Granted\n");
                return done;
            }
            printf("\nDenied\n");
            return done;

        }

        void* request_resources(void *arg){
            pthread_mutex_lock(&mutex);
            struct threadParams  *params = arg;
            int customer_num = params->threadNum;
            printf("\nCustomer %d is in critical\n", customer_num+1);
            int request[3];
            request[0] = params->req[0];
            request[1] = params->req[1];
            request[2] = params->req[2];

            int pass;
            for(int i = 0; i < NUMBER_OF_RESOURCES; i++){
                if(request[i] <= need[customer_num][i] && request[i] <= available[i]){
                    //printf("\nreq: %d, need: %d, avail: %d, alloc: %d\n\t", request[i], need[customer_num][i], available[i],allocation[customer_num][i]);
                    int state = safe_state(customer_num);

                    if(state == 1){
                        available[i] -= request[i];
                        allocation[customer_num][i] += request[i];
                        //printf("%d + %d\n", allocation[customer_num][i], request[i]);
                        need[customer_num][i] -= request[i];
                        pass = 1;

                    }
                    else if(state == -1){
                        printf("\nThe request from customer %d results in unsafe state\n", customer_num+1);
                        printf("\nreq: %d, need: %d, avail: %d, alloc: %d\n\t", request[i], need[customer_num][i], available[i],allocation[customer_num][i]);
                        pass = -1;
                        break;
                    }
                }
                else{
                    printf("\nreq: %d, need: %d, avail: %d\n", request[i], need[customer_num][i], available[i]);
                    printf("\nNot enough resources for customer %d's request or the customer doesn't need this resource.\n", customer_num);
                    pass = -1;
                    break;
                }
                printf("\nResource: %d req: %d, need: %d, avail: %d, alloc: %d\n\t",i+1, request[i], need[customer_num][i], available[i],allocation[customer_num][i]);

            }
            //printf("I'm a thread\n");
            pthread_mutex_unlock(&mutex);
            printf("\n Customer %d has left critical\n", customer_num+1);
            return pass;

        }

        int release_resources(int customer_num, int release[]){

        }

    int main(int argc, char *argv[]){
        pthread_t threads [NUMBER_OF_CUSTOMERS];
        int result;
        unsigned index = 0;

        // for(int ii = 0; ii < NUMBER_OF_CUSTOMERS; ii++){
            // for(int jj = 0; jj < NUMBER_OF_RESOURCES; jj++){
                // allocation[ii][jj] += 0;
            // }
        // }

        for(index = 0; index < NUMBER_OF_RESOURCES; index++){
            available[index] = strtol(argv[index+1], NULL,10);
        }

        for(int i = 0; i < NUMBER_OF_CUSTOMERS; i++){
            for(int j = 0; j < NUMBER_OF_RESOURCES; j++){
            maximum[i][j] = strtol(argv[j+1], NULL, 10)-4;
            need[i][j] = 2; //strtol(argv[j+1], NULL, 10) - 6;
            //printf("%d\t", maximum[i][j]);
            }
        }

        for(index = 0; index < NUMBER_OF_CUSTOMERS; index++){
            printf("\nCreating customer %d\n", index+1);
            struct threadParams params;
            params.req[0] = 2;
            params.req[1] = 2;
            params.req[2] = 2;
            params.threadNum = index;
            result = pthread_create(&threads[index],NULL,request_resources,&params);

        }

        for(index = 0; index < NUMBER_OF_CUSTOMERS; ++index){
            pthread_join(threads[index], NULL);
        }

        printf("\nDone");

    }

Body:
Finally, I found some time to handle this seriously:

I still have problems to understand your implementation in general. (I spent some hours to first understand Edsger Dijkstras Banker's algorithm itself before I came back.)

Thus, I do not understand why you distinguish need[] and threadParams.req[]. When I got it right this should actually be the same (i.e. one of them should not be there).

However, I want to show you what I got so far (which might be a help). After I studied and compared multiple samples I finally made a modified version of Banker's Algorithm on rosettacode.org:

#ifdef __cplusplus
#include <cassert>
#include <cstdio>
#include <cstring>
using namespace std;
#else /* (not) __cplusplus */
#include <assert.h>
#include <stdio.h>
#include <string.h>
#endif /* __cplusplus */

enum { nResources = 4 };
enum { nCustomers = 3 };

struct System {
  /* the total amount of resources */
  int total[nResources];
  /* the available amount of each resource */
  int available[nResources];
  /* currently allocated resources */
  int allocation[nCustomers][nResources];
  /* the maximum demand of each customer */
  int maximum[nCustomers][nResources];
};

static struct System testSetSafe1 = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 2, 2, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 3, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

static struct System testSetSafe2 = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 0, 0, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 5, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

static struct System testSetUnsafe = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 2, 2, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 5, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

void initSystem(struct System *pSystem)
{
  for (int j = 0; j < nResources; ++j) {
    pSystem->available[j] = pSystem->total[j];
    for (int i = 0; i < nCustomers; ++i) {
      pSystem->available[j] -= pSystem->allocation[i][j];
    }
  }
}

void printR(const char *title, int table[nResources])
{
  printf("%s:\n", title);
  for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
  printf("\n");
  for (int j = 0; j < nResources; ++j) printf("\t%d", table[j]);
  printf("\n");
}

void printCR(const char *title, int table[nCustomers][nResources])
{
  printf("%s:\n", title);
  for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
  printf("\n");
  for (int i = 0; i < nCustomers; ++i) {
    printf("C%d", i + 1);
    for (int j = 0; j < nResources; ++j) printf("\t%d", table[i][j]);
    printf("\n");
  }
}

int run(struct System *pSystem)
{
  initSystem(pSystem);
  printR("Total resources in system", pSystem->total);
  printR("Available resources", pSystem->available);
  printCR("Customers (currently allocated resources)",
    pSystem->allocation);
  printCR("Customers (maximum required resources", pSystem->maximum);
  int running[nCustomers];
  for (int count = nCustomers, safe; count;) {
    safe = 0;
    for (int i = 0; i < nCustomers; ++i) {
      if (running[i]) {
        int needed[nResources], blocked = 0;
        for (int j = 0, block; j < nResources; ++j) {
          needed[j]
            = pSystem->maximum[i][j] - pSystem->allocation[i][j];
          if ((block = needed[j] > pSystem->available[j])) {
            printf("Customer %d blocked due to resource %c\n",
              i + 1, 'A' + j);
          }
          blocked |= block;
        }
        if (!blocked) {
          printf("Customer %d is served.\n", i + 1);
          /* allocate resources */
          for (int j = 0; j < nResources; ++j) {
            pSystem->available[j] -= needed[j];
            pSystem->allocation[i][j] += needed[j];
            assert(pSystem->allocation[i][j] == pSystem->maximum[i][j]);
          }
          /* perform customer */
          printR("Allocated resources", pSystem->allocation[i]);
          running[i] = 0;
          printf("Customer %d is done.\n", i + 1);
          --count; /* customer finished */
          safe = 1; /* processes still safe (no deadlock) */
          /* free resources */
          for (int j = 0; j < nResources; ++j) {
            pSystem->available[j] += pSystem->allocation[i][j];
            pSystem->allocation[i][j] = 0;
          }
          break; /* bail out of inner loop */
        }
      }
    }
    if (!safe) {
      printf("Unsafe state (i.e. dead lock).\n");
      printR("Total resources in system", pSystem->total);
      printR("Available resources", pSystem->available);
      printCR("Customers (currently allocated resources)",
        pSystem->allocation);
      printCR("Customers (maximum required resources",
        pSystem->maximum);
      return -1;
    }
    printR("Available resources", pSystem->available);
  }
  return 0;
}

int main()
{
  /* 1st try: all requests can be granted soon */
  printf(
    "1st Run:\n"
    "========\n"
    "\n");
  run(&testSetSafe1);
  printf("\n");
  /* 2nd try: all requests can be granted by changing order */
  printf("2nd Run:\n"
    "========\n"
    "\n");
  run(&testSetSafe2);
  printf("\n");
  /* 3rd try: unsafe state */
  printf("3rd Run:\n"
    "========\n"
    "\n");
  run(&testSetUnsafe);
  printf("\n");
  /* done */
  printf("Done.\n");
  return 0;
}

(Debugged in VS2013 but) compiled and tested with gcc in cygwin on Windows 10 (64 bit):

$ gcc -std=c11 -x c bankers.cc -o bankers

$ ./bankers
1st Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      3       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Customer 1 is served.
Allocated resources:
        A       B       C       D
        3       3       2       2
Customer 1 is done.
Available resources:
        A       B       C       D
        4       3       3       3
Customer 2 is served.
Allocated resources:
        A       B       C       D
        1       2       3       4
Customer 2 is done.
Available resources:
        A       B       C       D
        5       3       6       6
Customer 3 is served.
Allocated resources:
        A       B       C       D
        1       3       5       0
Customer 3 is done.
Available resources:
        A       B       C       D
        6       5       7       6

2nd Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       3       3       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       0       0       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Customer 1 blocked due to resource A
Customer 2 is served.
Allocated resources:
        A       B       C       D
        1       2       3       4
Customer 2 is done.
Available resources:
        A       B       C       D
        4       3       6       5
Customer 1 is served.
Allocated resources:
        A       B       C       D
        5       3       2       2
Customer 1 is done.
Available resources:
        A       B       C       D
        5       3       6       6
Customer 3 is served.
Allocated resources:
        A       B       C       D
        1       3       5       0
Customer 3 is done.
Available resources:
        A       B       C       D
        6       5       7       6

3rd Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Customer 1 blocked due to resource A
Customer 2 blocked due to resource B
Customer 3 blocked due to resource C
Unsafe state (i.e. dead lock).
Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0

Done.

$

This looks quite good (for me).

Now, I made a derived sample introducing multi-threading.

A note about this:

The Wikipedia article Banker's algorithm states that the algorithm is intended for OS resource management like e.g. memory, semaphores and interface access. Sounds for me like, these algorithm is intended to manage things like muteces. Thus, a mutex should/can not be used for it and multi-threading makes not so much sense.

However, let forget about my concern and say this is for educational/understanding purpose:

#ifdef __cplusplus
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <mutex>
#include <thread>
using namespace std;
#else /* (not) __cplusplus */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#endif /* __cplusplus */

enum { nResources = 4 };
enum { nCustomers = 3 };

struct System {
  /* the total amount of resources */
  int total[nResources];
  /* the available amount of each resource */
  int available[nResources];
  /* currently allocated resources */
  int allocation[nCustomers][nResources];
  /* the maximum demand of each customer */
  int maximum[nCustomers][nResources];
  /* customers to serve, blocked customers */
  int running, blocked;
};

static struct System testSetSafe1 = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 2, 2, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 3, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

static struct System testSetSafe2 = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 0, 0, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 5, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

static struct System testSetUnsafe = {
  /* the total amount of resources */
  { 6, 5, 7, 6 },
  /* the available amount of each resource */
  { },
  /* currently allocated resources */
  {
    { 1, 2, 2, 1 },
    { 1, 0, 3, 3 },
    { 1, 2, 1, 0 }
  },
  /* the maximum demand of each customer */
  {
    { 5, 3, 2, 2 },
    { 1, 2, 3, 4 },
    { 1, 3, 5, 0 }
  }
};

void initSystem(struct System *pSystem)
{
  for (int j = 0; j < nResources; ++j) {
    pSystem->available[j] = pSystem->total[j];
    for (int i = 0; i < nCustomers; ++i) {
      pSystem->available[j] -= pSystem->allocation[i][j];
    }
  }
  pSystem->running = nCustomers; pSystem->blocked = 0;
}

void printR(const char *title, int table[nResources])
{
  printf("%s:\n", title);
  for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
  printf("\n");
  for (int j = 0; j < nResources; ++j) printf("\t%d", table[j]);
  printf("\n");
}

void printCR(const char *title, int table[nCustomers][nResources])
{
  printf("%s:\n", title);
  for (int j = 0; j < nResources; ++j) printf("\t%c", 'A' + j);
  printf("\n");
  for (int i = 0; i < nCustomers; ++i) {
    printf("C%d", i + 1);
    for (int j = 0; j < nResources; ++j) printf("\t%d", table[i][j]);
    printf("\n");
  }
}

struct Customer {
  int i;
  struct System *pSystem;
  int blocked;
};

static void initCustomer(
  struct Customer *pCustomer, int i, struct System *pSystem)
{
  pCustomer->i = i;
  pCustomer->pSystem = pSystem;
  pCustomer->blocked = 0;
}

#ifdef __cplusplus
/* multi-threading thin layer for C++ and std::thread */
static mutex mtx;
static inline void lockMutex(mutex *pMtx) { pMtx->lock(); }
static inline void unlockMutex(mutex *pMtx) { pMtx->unlock(); }
typedef std::thread Thread;
static inline int startThread(
  Thread *pThread,
  void* (*pThreadFunc)(Customer*), Customer *pCustomer)
{
  return (*pThread = Thread(pThreadFunc, pCustomer)).get_id()
    == Thread::id();
  /* thread creation failed -> thread id == thread::id() -> 1
   * thread creation successful -> thread id != thread::id() -> 0
   */
}
static inline void joinThread(Thread *pThread) { pThread->join(); }
#else /* (not) __cplusplus */
/* multi-threading thin layer for C and pthread */
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static void lockMutex(pthread_mutex_t *pMtx)
{
  pthread_mutex_lock(pMtx);
}
static void unlockMutex(pthread_mutex_t *pMtx)
{
  pthread_mutex_unlock(pMtx);
}
typedef pthread_t Thread;
static int startThread(
  Thread *pThread,
  void* (*pThreadFunc)(struct Customer*),
  struct Customer *pCustomer)
{
  return pthread_create(pThread, NULL,
    (void*(*)(void*))pThreadFunc, pCustomer);
}
static void joinThread(Thread *pThread) { pthread_join(*pThread, NULL); }
#endif /* __cplusplus */

void* runCustomer(struct Customer *pCustomer)
{
  int i = pCustomer->i;
  struct System *pSystem = pCustomer->pSystem;
  int needed[nResources];
  for (int j = 0; j < nResources; ++j) {
    needed[j] = pSystem->maximum[i][j] - pSystem->allocation[i][j];
  }
  for (int done = 0; !done;) {
    lockMutex(&mtx); /* thread-safe access to shared system */
    if (pCustomer->blocked) --pSystem->blocked;
    pCustomer->blocked = 0;
    for (int j = 0, block; j < nResources; ++j) {
      if ((block = needed[j] > pSystem->available[j])) {
        printf("Customer %d blocked due to resource %c\n",
          i + 1, 'A' + j);
      }
      pCustomer->blocked |= block;
    }
    if (!pCustomer->blocked) {
      printf("Customer %d is served.\n", i + 1);
      /* allocate resources */
      for (int j = 0; j < nResources; ++j) {
        pSystem->available[j] -= needed[j];
        pSystem->allocation[i][j] += needed[j];
        assert(pSystem->allocation[i][j] == pSystem->maximum[i][j]);
      }
      /* perform customer */
      printR("Allocated resources", pSystem->allocation[i]);
      --pSystem->running;
      done = 1; /* customer finished */
      printf("Customer %d is done.\n", i + 1);
      /* free resources */
      for (int j = 0; j < nResources; ++j) {
        pSystem->available[j] += pSystem->allocation[i][j];
        pSystem->allocation[i][j] = 0;
      }
    } else {
      ++pSystem->blocked;
      if ((done = pSystem->running <= pSystem->blocked)) {
        printf("Customer %d exited (due to dead-lock).\n", i + 1);
      }
    }
    unlockMutex(&mtx);
  }
  return 0;
}

int run(struct System *pSystem)
{
  initSystem(pSystem);
  printR("Total resources in system", pSystem->total);
  printR("Available resources", pSystem->available);
  printCR("Customers (currently allocated resources)",
    pSystem->allocation);
  printCR("Customers (maximum required resources", pSystem->maximum);
  /* created threads for customers */
  lockMutex(&mtx); /* force concurrency a little bit */
  Thread threads[nCustomers];
  struct Customer customers[nCustomers];
  for (int i = 0; i < nCustomers; ++i) {
    printf("Creating customer %d\n", i + 1);
    initCustomer(customers + i, i, pSystem);
    if (startThread(threads + i, &runCustomer, customers + i)) {
      printf("ERROR: Failed to start thread for customer %d!\n", i + 1);
    }
  }
  /* unlock mutex to let threads compete */
  printf("Ready, steady, go...\n");
  unlockMutex(&mtx);
  /* join all threads */
  for (int i = 0; i < nCustomers; ++i) joinThread(threads + i);
  /* report */
  if (pSystem->blocked) {
    printf("Unsafe state (i.e. dead lock).\n");
    printR("Total resources in system", pSystem->total);
    printR("Available resources", pSystem->available);
    printCR("Customers (currently allocated resources)",
      pSystem->allocation);
    printCR("Customers (maximum required resources",
      pSystem->maximum);
    return -1;
  }
  return 0;
}

int main()
{
  /* 1st try: all requests can be granted soon */
  printf(
    "1st Run:\n"
    "========\n"
    "\n");
  run(&testSetSafe1);
  printf("\n");
  /* 2nd try: all requests can be granted by changing order */
  printf("2nd Run:\n"
    "========\n"
    "\n");
  run(&testSetSafe2);
  printf("\n");
  /* 3rd try: unsafe state */
  printf("3rd Run:\n"
    "========\n"
    "\n");
  run(&testSetUnsafe);
  printf("\n");
  /* done */
  printf("Done.\n");
  return 0;
}

(Again debugged in VS2013 but) compiled and tested with gcc in cygwin on Windows 10 (64 bit):

$ gcc -std=c11 -x c bankersMT.cc -o bankersMT -pthread

$ ./bankersMT
1st Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      3       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Creating customer 1
Creating customer 2
Creating customer 3
Ready, steady, go...
Customer 1 is served.
Allocated resources:
        A       B       C       D
        3       3       2       2
Customer 1 is done.
Customer 2 is served.
Allocated resources:
        A       B       C       D
        1       2       3       4
Customer 2 is done.
Customer 3 is served.
Allocated resources:
        A       B       C       D
        1       3       5       0
Customer 3 is done.

2nd Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       3       3       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       0       0       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Creating customer 1
Creating customer 2
Creating customer 3
Ready, steady, go...
Customer 1 blocked due to resource A
Customer 2 is served.
Allocated resources:
        A       B       C       D
        1       2       3       4
Customer 2 is done.
Customer 3 is served.
Allocated resources:
        A       B       C       D
        1       3       5       0
Customer 3 is done.
Customer 1 is served.
Allocated resources:
        A       B       C       D
        5       3       2       2
Customer 1 is done.

3rd Run:
========

Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0
Creating customer 1
Creating customer 2
Creating customer 3
Ready, steady, go...
Customer 1 blocked due to resource A
Customer 2 blocked due to resource B
Customer 3 blocked due to resource C
Customer 3 exited (due to dead-lock).
Customer 1 blocked due to resource A
Customer 1 exited (due to dead-lock).
Customer 2 blocked due to resource B
Customer 2 exited (due to dead-lock).
Unsafe state (i.e. dead lock).
Total resources in system:
        A       B       C       D
        6       5       7       6
Available resources:
        A       B       C       D
        3       1       1       2
Customers (currently allocated resources):
        A       B       C       D
C1      1       2       2       1
C2      1       0       3       3
C3      1       2       1       0
Customers (maximum required resources:
        A       B       C       D
C1      5       3       2       2
C2      1       2       3       4
C3      1       3       5       0

Done.

$

Although, this looks quite good also, I'm not sure about whether the dead-lock detection is 100 % correct. Because multi-threading introduces non-deterministics, this is hard to test. I tried to "debug it by head" but ended up with headache...

Note about implementation:

I used the thin-layer for multi-threading, again. Thus, these samples can be compiled in C++ (std::thread, VS2013/g++) as well as in C (pthread, gcc).


来源: stackexchange

问:
Nativescript Render Component after the page has loaded
I am trying to add WikitudeArchitectView to my typescript code, I registered the element to the main.ts typescript file:

var architectView = require("nativescript-wikitudearchitectview");
registerElement("ArchitectView", () => architectView.ArchitectView);```
</div>
</div>

 in the XML file i have added the ArchitectView element tag: </p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code><StackLayout>

  <ArchitectView urlString="http://10.20.30.79:8888" urlLoaded='urlLoaded' urlLoadError='urlLoadError' urlInvoked='urlInvoked'>
  </ArchitectView>

</StackLayout></code>```

when i run the code on my Device i get the error

So I think i need to find a way to render the  after the page has loaded (maybe using ngOnInit) i dont know how to do this

答:
Hey you can achieve to render after the page has loaded by using ngAfterViewInit.I am also writing the code for ngOnInit.

Here is the bit of code to help you.

```<code>import { Component, ElementRef,AfterViewInit, OnInit, ViewChild } from "@angular/core";
export class DuesComponent implements OnInit AfterViewInit { }

 ngAfterViewInit() {
 <Write your logic inside this funtion>
 }

  ngOnInit() {
  }
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am trying to add WikitudeArchitectView to my typescript code, I registered the element to the main.ts typescript file:

var architectView = require("nativescript-wikitudearchitectview");
registerElement("ArchitectView", () => architectView.ArchitectView);

 in the XML file i have added the ArchitectView element tag:

<StackLayout>

  <ArchitectView urlString="http://10.20.30.79:8888" urlLoaded='urlLoaded' urlLoadError='urlLoadError' urlInvoked='urlInvoked'>
  </ArchitectView>

</StackLayout>

when i run the code on my Device i get the error

So I think i need to find a way to render the  after the page has loaded (maybe using ngOnInit) i dont know how to do this

Body:
Hey you can achieve to render after the page has loaded by using ngAfterViewInit.I am also writing the code for ngOnInit.

Here is the bit of code to help you.

import { Component, ElementRef,AfterViewInit, OnInit, ViewChild } from "@angular/core";
export class DuesComponent implements OnInit AfterViewInit { }

 ngAfterViewInit() {
 <Write your logic inside this funtion>
 }

  ngOnInit() {
  }


问:
Can AWS lambda listen to S3 createobject events when files are dropped manually
I have and s3 bucket and lambda function, this function has trigger which listens to s3 createobject events. somehow some are missed in s3, i am planning to drop them manually. Can my lambda function will get the events like before?

Also i will put files in different folders based on date. will i get different events on each file drop?

答: To answer the second question: Yes, every time a file is added to your bucket (assuming that the Lambda function is listening for changes on in all folders and not just a prefix), your lambda function will receive an event object that will contain information about that file.


问:
Shortest paths without supernodes in Neo4j
I have a graph with 0.5 billion of nodes and edges in Neo. I want to find shortest path between 2 nodes that avoids supernodes (even if it is longer than paths having supernodes on them).

The below query works fine for smaller graphs, but never finishes for the graph of the size I am dealing with:

```<code>MATCH (n:Node { id:'123'}),(m:Node { id:'234' }), p = shortestPath((n)-[*..6]-(m))
WHERE NONE(x IN NODES(p) WHERE size((x)--())>1000)
RETURN p
</code>```

If I remove the WHERE clause it is super fast. Typically subsecond.

How can I speed it up? Would precalculating node degrees and indexing them help? Should I resort to duplicating all the edges apart from the ones adjacent to supernodes, giving them a new label and using them for my shortestPath query without the WHERE clause? Any other suggestions?

答:
You could also try to add a label for supernodes:

```<code>MATCH (x:Node)
WHERE size((x)--())>1000
SET n:Supernode
</code>```

Does this run and finish on your data? How many supernodes and normal nodes do you have?

Then try:

```<code>MATCH (n:Node { id:'123'}),(m:Node { id:'234' })
WITH n, m
MATCH p = shortestPath((n)-[*..6]-(m))
WHERE NONE(x IN NODES(p) WHERE (x:Supernode))
RETURN p
</code>```

I suppose a label check is faster.

Body:
I have a graph with 0.5 billion of nodes and edges in Neo. I want to find shortest path between 2 nodes that avoids supernodes (even if it is longer than paths having supernodes on them).

The below query works fine for smaller graphs, but never finishes for the graph of the size I am dealing with:

MATCH (n:Node { id:'123'}),(m:Node { id:'234' }), p = shortestPath((n)-[*..6]-(m))
WHERE NONE(x IN NODES(p) WHERE size((x)--())>1000)
RETURN p

If I remove the WHERE clause it is super fast. Typically subsecond.

How can I speed it up? Would precalculating node degrees and indexing them help? Should I resort to duplicating all the edges apart from the ones adjacent to supernodes, giving them a new label and using them for my shortestPath query without the WHERE clause? Any other suggestions?

Body:
You could also try to add a label for supernodes:

MATCH (x:Node)
WHERE size((x)--())>1000
SET n:Supernode

Does this run and finish on your data? How many supernodes and normal nodes do you have?

Then try:

MATCH (n:Node { id:'123'}),(m:Node { id:'234' })
WITH n, m
MATCH p = shortestPath((n)-[*..6]-(m))
WHERE NONE(x IN NODES(p) WHERE (x:Supernode))
RETURN p

I suppose a label check is faster.


问:
How to dynamic output a file content with replaced some bytes?

I used a fuse plugin named 'concatfs'

It can virtual merge some file with a specific filename like xxx-concat-.mkv,
  and this file's content is a TEXT:

```<code>1.mkv
2.mkv
3.mkv
</code>```

system reads xxx-concat-.mkv, it outputs a merged file with 1.mkv 2.mkv .... but the files are not merged in fact, it's a virtual output.

So, My question is :

a static file, 1.zip > 300 MB.

It has so many copies(publish to many people), and the difference is only 4 bytes offset: 0xa 0xb 0xc 0xd in these copies. the 4 bytes is people's id

so I wanna make a file named '1-replaced-123.zip' like concatfs, content mostly like:(all binary)

1.zip

0xa 4 replaced-4bytes-binary-content

0x1111 10 replaced-10bytes-binary-content

system reads 1-replaced-123.zip, the fuse will outputing the replaced content.

It can saves so many disk space.

And I known PHP/JSP can read and echo with replaced, but php will using a high cpu/memory to echo big file stream.

do you have some suggestion?

Thanks a lot, and sorry for my english.

答:
Use merged-fuse to virtual merge/replace files (C++ 11)

https://github.com/fly-studio/merged-fuse

Example

1.txt

```<code>12345678
</code>```

2.txt

```<code>abcdefghi
</code>```

Make a file named 1-merged-.txt,

-merged- is a special words in the file name

content is JSON format

```<code>[
    {
        "path": "1.txt"
    },
    {
        "path": "2.txt",
        "replaces": [
             {
                 "offset": 2,
                 "length": 2,
                 "content": "MjE="
             }
        ]
    }
]
</code>```

When cat 1-merged-.txt, output:

```<code>12345678ab12efghi
</code>```

You can see the files were merged(virtual), and the content was replaced:

cd replaced to 12

Body:
I used a fuse plugin named 'concatfs'

It can virtual merge some file with a specific filename like xxx-concat-.mkv,
  and this file's content is a TEXT:

1.mkv
2.mkv
3.mkv

system reads xxx-concat-.mkv, it outputs a merged file with 1.mkv 2.mkv .... but the files are not merged in fact, it's a virtual output.

So, My question is :

a static file, 1.zip > 300 MB.

It has so many copies(publish to many people), and the difference is only 4 bytes offset: 0xa 0xb 0xc 0xd in these copies. the 4 bytes is people's id

so I wanna make a file named '1-replaced-123.zip' like concatfs, content mostly like:(all binary)

1.zip

0xa 4 replaced-4bytes-binary-content

0x1111 10 replaced-10bytes-binary-content

system reads 1-replaced-123.zip, the fuse will outputing the replaced content.

It can saves so many disk space.

And I known PHP/JSP can read and echo with replaced, but php will using a high cpu/memory to echo big file stream.

do you have some suggestion?

Thanks a lot, and sorry for my english.

Body:
Use merged-fuse to virtual merge/replace files (C++ 11)

https://github.com/fly-studio/merged-fuse

Example

1.txt

12345678

2.txt

abcdefghi

Make a file named 1-merged-.txt,

-merged- is a special words in the file name

content is JSON format

[
    {
        "path": "1.txt"
    },
    {
        "path": "2.txt",
        "replaces": [
             {
                 "offset": 2,
                 "length": 2,
                 "content": "MjE="
             }
        ]
    }
]

When cat 1-merged-.txt, output:

12345678ab12efghi

You can see the files were merged(virtual), and the content was replaced:

cd replaced to 12


问:
Is there a way to retrieve single row from database as key value only in laravel
can i retrieve single row from database like this in Laravel</p>

```<code>["name"=>"jhon",
"age"=>"18"
]
</code>```

答:
Use first() method along with id because id is unique key for every row

```<code> User::whereId($id)->first();
</code>```

Body:
can i retrieve single row from database like this in Laravel

["name"=>"jhon",
"age"=>"18"
]

Body:
Use first() method along with id because id is unique key for every row

 User::whereId($id)->first();


问:
How to substring Android logcat output and show only the message itself
I would like to use logcat and output only the messages themselves.
Not the method name, not the time, not the tag - just the message.

Example, from this message:

D/ConnectivityService(  471): Setting tx/rx TCP buffers to
  524288,1048576,2097152,262144,524288,1048576

I only want the

Setting tx/rx TCP buffers to
  524288,1048576,2097152,262144,524288,1048576

Is that possible ?

答: Yes, you can do adb logcat -v raw to get rid of the tags and use pipe | grep -i "" to substring that output if you know what you're searching for. Otherwise, ephemient's answer is perfect. Does that answer your questions (as it seemed to be twofold)?


问:
Can't set DataTables column width on a dynamically generated table
I have some jquery that posts some data, gets a list back as a JSON response and builds a datatable based on the list data. Everything works well, however I have one seemingly simple issue:
I cannot get the column widths in my table declaration to to persist.

My code looks something like this:

```<code>//some magic happens and I get a result like this
json_result = ['eggs', 'bananas', 'purple']

//declare the table
var result_table = $( table_selector )
table = result_table.DataTable({
              //set two different width columns
              columnDefs: [
                     { "width": "10%", "targets": 0 },
                     { "width": "90%", "targets": 1 }
                    ]
          });

//build the table rows based on result
for (i=0, i<json_result.length, i++){
    var new_row = '<tr><td><input type="checkbox"></td><td>' +json_result[i] + '</td></tr>'
    table.row.add(new_row).draw();
   }

// table.columns.adjust().draw(); <-- tried this to no avail
table.draw();
</code>```

The result is a perfectly good table that fits well in it's container...but the column widths are split 50/50. These same column defs seem to work fine on other tables in my application. I feel like I'm missing something simple!

答:
From a forum thread here datatables.net, disable the "auto width" functionality via:

```<code>$(document).ready( function () {
  $('#example').dataTable( {
    "bAutoWidth": false
  } );
} );
</code>```

Reference: legacy.datatables.net:

Body:
I have some jquery that posts some data, gets a list back as a JSON response and builds a datatable based on the list data. Everything works well, however I have one seemingly simple issue:
I cannot get the column widths in my table declaration to to persist.

My code looks something like this:

//some magic happens and I get a result like this
json_result = ['eggs', 'bananas', 'purple']

//declare the table
var result_table = $( table_selector )
table = result_table.DataTable({
              //set two different width columns
              columnDefs: [
                     { "width": "10%", "targets": 0 },
                     { "width": "90%", "targets": 1 }
                    ]
          });

//build the table rows based on result
for (i=0, i<json_result.length, i++){
    var new_row = '
<input type="checkbox">	' +json_result[i] + '
'
    table.row.add(new_row).draw();
   }

// table.columns.adjust().draw(); <-- tried this to no avail
table.draw();

The result is a perfectly good table that fits well in it's container...but the column widths are split 50/50. These same column defs seem to work fine on other tables in my application. I feel like I'm missing something simple!

Body:
From a forum thread here datatables.net, disable the "auto width" functionality via:

$(document).ready( function () {
  $('#example').dataTable( {
    "bAutoWidth": false
  } );
} );

Reference: legacy.datatables.net:


问:
for-loop over directory to zip subdirectories
My question is really simple but it's been too long since I last read bash-scripts so I cannot understand bash anymore...

I have a folder (name containing spaces) which has x subfolders. Now I want to zip each subfolder in its own zip archive.

The following script is what I have:

```<code>#!/bin/bash
cd $1
for folder in $1/* do
zip -r "${folder%/}" "${folder%/}"
done
</code>```

every time I try to execute it with ./test.sh . I just get

```<code>./test.sh: line 4: syntax error near unexpected token `zip'
./test.sh: line 4: `zip -r "${folder%/}" "${folder%/}"'
</code>```

what is wrong with my thoughts and why?

if I enter a variable (e.g. file="subfolder i want to zip") in the shell and execute zip -r "${file}" "${file}" it just works fine for the one folder.

I appreciate any help and hope my question can be solved easily (so I'm able to understand it).
Thanks a lot in advance.

答:
Someone already mentioned it, but you do need a semi color before the do

I would also recommend checking if you are really zipping up a directory.

```<code>#!/bin/bash
cd $1
for folder in $1/* ; do
    [ -d $folder ] && zip -r "${folder%/}" "${folder%/}"
done
</code>```

Body:
My question is really simple but it's been too long since I last read bash-scripts so I cannot understand bash anymore...

I have a folder (name containing spaces) which has x subfolders. Now I want to zip each subfolder in its own zip archive.

The following script is what I have:

#!/bin/bash
cd $1
for folder in $1/* do
zip -r "${folder%/}" "${folder%/}"
done

every time I try to execute it with ./test.sh . I just get

./test.sh: line 4: syntax error near unexpected token `zip'
./test.sh: line 4: `zip -r "${folder%/}" "${folder%/}"'

what is wrong with my thoughts and why?

if I enter a variable (e.g. file="subfolder i want to zip") in the shell and execute zip -r "${file}" "${file}" it just works fine for the one folder.

I appreciate any help and hope my question can be solved easily (so I'm able to understand it).
Thanks a lot in advance.

Body:
Someone already mentioned it, but you do need a semi color before the do

I would also recommend checking if you are really zipping up a directory.

#!/bin/bash
cd $1
for folder in $1/* ; do
    [ -d $folder ] && zip -r "${folder%/}" "${folder%/}"
done


问:
start the service when app gets closed
I want to start a service when I press the home button or just press back (when the app is in the background but not killed)
how can I do a function that checks that ?
thanks to all</p>

答: You can implement Application.ActivityLifecycleCallbacks and attach it to your Application to now when your app is in background. Here is Foreground example.</p>

Title: start the service when app gets closed


问:
Opencart 2.1.0.2 Getting error from installing ocmod.zip
I've just started to use 2.1.0.2 and I'm trying to convert over some of my own extensions I built for my 1.5.6.4 store.

I have started with a fresh install of 2.1.0.2 and I built a very basic extension, I'm wanting to move over to the extension installer to install my future additions to my store instead of using vqmod.

I have made my testerextension.ocmod.zip, inside this is:

```<code>install.xml
/upload/
/admin/
/catalog/
</code>```

However when I use the installer to upload testerextension.ocmod.zip I'm getting the following error:

Directory containing files to be uploaded could not be found

I have tracked this down to the ftp() class as I can see this error can be trigged in another class.

I've also looked into the storage temp folder to find a folder unzipped called: testerextension.ocmod NOT upload.

To rule out if there was an issue with OC system I have uploaded another extension from the extension store with the similar directory structure and similar ocmod.zip name only for it to correctly install.

Therefore i'm unsure as to why this would be happening, I understand the system is looking for the upload folder in the temp folder but it's not there as it's one level deeper in the testerextension.ocmod - but as you can see from the directory structure above this shouldn't be happening.

Does anyone have any idea where I could be going wrong?

答:
I had the same problem.

This happened cause I compressed the directory of the extension. The rigth way is compress the files of the extension.

Body:
I've just started to use 2.1.0.2 and I'm trying to convert over some of my own extensions I built for my 1.5.6.4 store.

I have started with a fresh install of 2.1.0.2 and I built a very basic extension, I'm wanting to move over to the extension installer to install my future additions to my store instead of using vqmod.

I have made my testerextension.ocmod.zip, inside this is:

install.xml
/upload/
/admin/
/catalog/

However when I use the installer to upload testerextension.ocmod.zip I'm getting the following error:

Directory containing files to be uploaded could not be found

I have tracked this down to the ftp() class as I can see this error can be trigged in another class.

I've also looked into the storage temp folder to find a folder unzipped called: testerextension.ocmod NOT upload.

To rule out if there was an issue with OC system I have uploaded another extension from the extension store with the similar directory structure and similar ocmod.zip name only for it to correctly install.

Therefore i'm unsure as to why this would be happening, I understand the system is looking for the upload folder in the temp folder but it's not there as it's one level deeper in the testerextension.ocmod - but as you can see from the directory structure above this shouldn't be happening.

Does anyone have any idea where I could be going wrong?


问:
Read a variable length integer from the supplied InputStream
I was looking a bit above the Netflix Hollow library code (https://github.com/Netflix/hollow) and I found this function to which I can't find any sense (Warning: I don't know much about Java ).
Theoretically, the function returns a variable-length integer from the InputStream.

```<code>/**
 * Read a variable length integer from the supplied InputStream
 */
public static int readVInt(InputStream in) throws IOException {
    byte b = (byte)in.read();

    if(b == (byte) 0x80)
        throw new RuntimeException("Attempting to read null value as int");

    int value = b & 0x7F;
    while ((b & 0x80) != 0) {
      b = (byte)in.read();
      value <<= 7;
      value |= (b & 0x7F);
    }

    return value;
}
</code>```

I comment my doubts:

1) Int value = b & 0x7F : The result of this is always b, right? What's the point?

2) while ((b & 0x80) != 0) : The result of b & 0x80 (If b is an integer digit, that is, coded in decimal from 0 to 9, would be 48-57 in decimal) is always 0. Therefore, will never enter the loop...

答:
Honestly, it's kind of weird (IMHO) to find such low level implementations in Java; this kind of logic is more usual in C programs and other "close to the metal" languages. But I guess efficient streaming to millions of users doesn't come for free :)

b is a byte, not an integer. It's interpreted as 8 bits.

0x80 is 10000000, a mask with all bits set to zero except the higher-order ("first") one.

0x7F is 01111111, a mask with all bits set to one except the first one. The inverse of 0x80.

value is the integer value we want to read. This is an int which is 4 bytes in Java. So 00000000000000000000000000000000 initially.

The code reads a sequence of bytes, one by one. It uses the first bit as a mark for termination (0 means "last byte"), and concatenates the other 7 bits to value. The masks are applied to evaluate just those bits. So b & 0x80 is used to check if the first bit is set, while b & 0x7F is used to set the first bit to zero and keep the value of all the other bits.

Example:

We want to transmit the number 24612135 byte per byte. This is 1011101111000110100100111 in binary.

We split it in groups of 7 bits: 0001011 1011110 0011010 0100111 and make every group a 1-leading 8-bit byte, save for the last one which will be marked as 0-leading: 10001011 11011110 10011010 00100111

First byte gets read. So b = 10001011. Since this is not 0x80 (10000000), we know this is going to be a valid, non-null integer.

We discard the first bit (b & 0x7f is 00001011) and set value to that. Now value is 00000000000000000000000000001011

Now this could be a one-byte number, so we have to check for the first bit to know if we should continue reading. b & 0x80 is not 0, so we enter the loop to read more bytes.

Read the second byte. Now b = 11011110. Discard first bit (b & 0x7f) and put the other 7 bits inside value. But value already has some bits set, so we have to shift them to make room for 7 more bits: value <<= 7. Now value is 00000000000000000000010110000000. By using the bitwise OR operator value |= (b & 0x7F) we set the lowest 7 bits to the right value. Now value is 00000000000000000000010111011110.

The second byte didn't have the first bit set to 0 either, so we loop again for the third byte. Same logic; now value is 00000000000000101110111100011010.

The third byte also didn't have the first bit set to 0; loop again for the fourth byte, 00100111. Now value is 00000001011101111000110100100111. This is the correct value that we intended to send.

Because the fourth byte did have the first bit set to zero, the loop's break condition now evaluates to true, so we stop reading bytes.

Anyways, I hope this helped you.

Body:
I was looking a bit above the Netflix Hollow library code (https://github.com/Netflix/hollow) and I found this function to which I can't find any sense (Warning: I don't know much about Java ).
Theoretically, the function returns a variable-length integer from the InputStream.

/**
 * Read a variable length integer from the supplied InputStream
 */
public static int readVInt(InputStream in) throws IOException {
    byte b = (byte)in.read();

    if(b == (byte) 0x80)
        throw new RuntimeException("Attempting to read null value as int");

    int value = b & 0x7F;
    while ((b & 0x80) != 0) {
      b = (byte)in.read();
      value <<= 7;
      value |= (b & 0x7F);
    }

    return value;
}

I comment my doubts:

1) Int value = b & 0x7F : The result of this is always b, right? What's the point?

2) while ((b & 0x80) != 0) : The result of b & 0x80 (If b is an integer digit, that is, coded in decimal from 0 to 9, would be 48-57 in decimal) is always 0. Therefore, will never enter the loop...


问:
SwipeRefreshLayout + ViewPager, limit horizontal scroll only?
I've implemented SwipeRefreshLayout and ViewPager in my app but there is a big trouble: whenever I'm going to swipe left / right to switch between pages the scrolling is too sensitive. A little swipe down will trigger the SwipeRefreshLayout refresh too.

I want to set a limit to when horizontal swipe starts, then force horizontal only until swiping is over. In other words, I want to cancel vertical swipping when finger is moving horizontally.

This problem only occurs on ViewPager, if I swipe down and SwipeRefreshLayout refresh function is triggered (the bar is shown) and then I move my finger horizontally, it still only allows vertical swipes.

I've tried to extend the ViewPager class but it isn't working at all:

```<code>public class CustomViewPager extends ViewPager {

    public CustomViewPager(Context ctx, AttributeSet attrs) {
        super(ctx, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean in = super.onInterceptTouchEvent(ev);
        if (in) {
            getParent().requestDisallowInterceptTouchEvent(true);
            this.requestDisallowInterceptTouchEvent(true);
        }
        return false;
    }

}
</code>```

Layout xml:

```<code><android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/viewTopic"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.myapp.listloader.foundation.CustomViewPager
        android:id="@+id/topicViewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
</code>```

any help would be appreciated, thanks

答:
There is one problem with the solution of nhasan:

If the horizontal swipe that triggers the setEnabled(false) call on the SwipeRefreshLayout in the OnPageChangeListener happens when the SwipeRefreshLayout has already recognized a Pull-to-Reload but has not yet called the notification callback, the animation disappears but the internal state of the SwipeRefreshLayout stays on "refreshing" forever as no notification callbacks are called that could reset the state. From a user perspective this means that Pull-to-Reload is not working anymore as all pull gestures are not recognized.

The problem here is that the disable(false) call removes the animation of the spinner and the notification callback is called from the onAnimationEnd method of an internal AnimationListener for that spinner which is set out of order that way.

It took admittedly our tester with the fastest fingers to provoke this situation but it can happen once in a while in realistic scenarios as well.

A solution to fix this is to override the onInterceptTouchEvent method in SwipeRefreshLayout as follows:

```<code>public class MySwipeRefreshLayout extends SwipeRefreshLayout {

    private boolean paused;

    public MySwipeRefreshLayout(Context context) {
        super(context);
        setColorScheme();
    }

    public MySwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        setColorScheme();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (paused) {
            return false;
        } else {
            return super.onInterceptTouchEvent(ev);
        }
    }

    public void setPaused(boolean paused) {
        this.paused = paused;
    }
}
</code>```

Use the MySwipeRefreshLayout in your Layout - File and change the code in the solution of mhasan to

```<code>...

@Override
public void onPageScrollStateChanged(int state) {
    swipeRefreshLayout.setPaused(state != ViewPager.SCROLL_STATE_IDLE);
}

...
</code>```

Body:
I've implemented SwipeRefreshLayout and ViewPager in my app but there is a big trouble: whenever I'm going to swipe left / right to switch between pages the scrolling is too sensitive. A little swipe down will trigger the SwipeRefreshLayout refresh too.

I want to set a limit to when horizontal swipe starts, then force horizontal only until swiping is over. In other words, I want to cancel vertical swipping when finger is moving horizontally.

This problem only occurs on ViewPager, if I swipe down and SwipeRefreshLayout refresh function is triggered (the bar is shown) and then I move my finger horizontally, it still only allows vertical swipes.

I've tried to extend the ViewPager class but it isn't working at all:

public class CustomViewPager extends ViewPager {

    public CustomViewPager(Context ctx, AttributeSet attrs) {
        super(ctx, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean in = super.onInterceptTouchEvent(ev);
        if (in) {
            getParent().requestDisallowInterceptTouchEvent(true);
            this.requestDisallowInterceptTouchEvent(true);
        }
        return false;
    }

}

Layout xml:

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/viewTopic"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.myapp.listloader.foundation.CustomViewPager
        android:id="@+id/topicViewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>

any help would be appreciated, thanks

Body:
There is one problem with the solution of nhasan:

If the horizontal swipe that triggers the setEnabled(false) call on the SwipeRefreshLayout in the OnPageChangeListener happens when the SwipeRefreshLayout has already recognized a Pull-to-Reload but has not yet called the notification callback, the animation disappears but the internal state of the SwipeRefreshLayout stays on "refreshing" forever as no notification callbacks are called that could reset the state. From a user perspective this means that Pull-to-Reload is not working anymore as all pull gestures are not recognized.

The problem here is that the disable(false) call removes the animation of the spinner and the notification callback is called from the onAnimationEnd method of an internal AnimationListener for that spinner which is set out of order that way.

It took admittedly our tester with the fastest fingers to provoke this situation but it can happen once in a while in realistic scenarios as well.

A solution to fix this is to override the onInterceptTouchEvent method in SwipeRefreshLayout as follows:

public class MySwipeRefreshLayout extends SwipeRefreshLayout {

    private boolean paused;

    public MySwipeRefreshLayout(Context context) {
        super(context);
        setColorScheme();
    }

    public MySwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        setColorScheme();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (paused) {
            return false;
        } else {
            return super.onInterceptTouchEvent(ev);
        }
    }

    public void setPaused(boolean paused) {
        this.paused = paused;
    }
}

Use the MySwipeRefreshLayout in your Layout - File and change the code in the solution of mhasan to

...

@Override
public void onPageScrollStateChanged(int state) {
    swipeRefreshLayout.setPaused(state != ViewPager.SCROLL_STATE_IDLE);
}

...


问:
Codeigniter - failed to open stream: HTTP wrapper does not support writeable connections
I have a problem in upload picture in codeigniter
this is my view:

```<code><form method="post" action="<? echo site_url('do_upload'); ?>" id="createForm"  enctype="multipart/form-data" >
        <div style="display:none">
        <input type="hidden" name="<?php echo $this->security->get_csrf_token_name(); ?>" value="<?php echo $this->security->get_csrf_hash();?>" />
        </div>

      <div class="form-group">
        <label for="exampleInputFile">Picture</label>
        <input type="file" name="picture" id="exampleInputFile">
        <p class="help-block">Choose file to upload.</p>
      </div>

    </div>
    <div class="modal-footer">
    <button type="submit" class="btn btn-primary">Save changes</button>
    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</form>
</code>```

my controller:

```<code>public function do_upload()
{
    if(isset($_FILES['picture']))
    {
         $dossier = base_url().'assets/image/product/';
         $fichier = basename($_FILES['picture']['name']);
         if(move_uploaded_file($_FILES['picture']['tmp_name'], $dossier . $fichier)) //Si la fonction renvoie TRUE, c'est que ça a fonctionné...
         {
              echo 'Upload effectué avec succès !';
         }
         else //Sinon (la fonction renvoie FALSE).
         {
              echo 'Echec de l\'upload !';
         }
    }
}
</code>```

and I have all time this problem:

Screen shot error

答:
File Upload function does not support HTTP & https based file path. also if you are used linux based os like ubuntu or mac to give the folder permission is 777 of all folder for ex. assets , image and product those three folder need read & write permission 777</p>

```<code>public function do_upload()
{
    if(isset($_FILES['picture']))
    {
         $dossier ='./assets/image/product/'; //based folder path if is inside public so u can use $dossier = './public/assets/image/product/';
         $fichier = basename($_FILES['picture']['name']);
         if(move_uploaded_file($_FILES['picture']['tmp_name'], $dossier . $fichier)) //Si la fonction renvoie TRUE, c'est que ça a fonctionné...
         {
              echo 'Upload effectué avec succès !';
         }
         else //Sinon (la fonction renvoie FALSE).
         {
              echo 'Echec de l\'upload !';
         }
    }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have a problem in upload picture in codeigniter
this is my view:

<form method="post" action="<? echo site_url('do_upload'); ?>" id="createForm"  enctype="multipart/form-data" >

        <input type="hidden" name="<?php echo $this->security->get_csrf_token_name(); ?>" value="<?php echo $this->security->get_csrf_hash();?>" />

        Picture
        <input type="file" name="picture" id="exampleInputFile">

Choose file to upload.

    <button type="submit" class="btn btn-primary">Save changes</button>
    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</form>

my controller:

public function do_upload()
{
    if(isset($_FILES['picture']))
    {
         $dossier = base_url().'assets/image/product/';
         $fichier = basename($_FILES['picture']['name']);
         if(move_uploaded_file($_FILES['picture']['tmp_name'], $dossier . $fichier)) //Si la fonction renvoie TRUE, c'est que ça a fonctionné...
         {
              echo 'Upload effectué avec succès !';
         }
         else //Sinon (la fonction renvoie FALSE).
         {
              echo 'Echec de l\'upload !';
         }
    }
}

and I have all time this problem:

Screen shot error

Body:
File Upload function does not support HTTP & https based file path. also if you are used linux based os like ubuntu or mac to give the folder permission is 777 of all folder for ex. assets , image and product those three folder need read & write permission 777

public function do_upload()
{
    if(isset($_FILES['picture']))
    {
         $dossier ='./assets/image/product/'; //based folder path if is inside public so u can use $dossier = './public/assets/image/product/';
         $fichier = basename($_FILES['picture']['name']);
         if(move_uploaded_file($_FILES['picture']['tmp_name'], $dossier . $fichier)) //Si la fonction renvoie TRUE, c'est que ça a fonctionné...
         {
              echo 'Upload effectué avec succès !';
         }
         else //Sinon (la fonction renvoie FALSE).
         {
              echo 'Echec de l\'upload !';
         }
    }
}


问:
What do @backups branches/tags mean in converted svn2git git repository
After converting a SVN repository from SVN to git, I see tags with names like:

```<code>backups/PM_4_2_11@204843
</code>```

This tag was not in the original SVN repository. Does anyone know what it means?

答: It means you had that tag in SVN revision 204843, but it was deleted in SVN after that.

Body:
After converting a SVN repository from SVN to git, I see tags with names like:

backups/PM_4_2_11@204843

This tag was not in the original SVN repository. Does anyone know what it means?