Threads are lightweight processes that share the same address space. The Linux implementation uses clone() to create threads that have separate thread IDs but share other attributes like the virtual memory. Pthreads provides objects and functions for thread management including creation, attributes, mutual exclusion with mutexes and condition variables, cancellation, and thread-specific data.
Axa Assurance Maroc - Insurer Innovation Award 2024
Sysprog 14
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13. static RETSIGTYPE sigexit_handler(int signum) { int i; nslcd_exitsignal=signum; /* cancel all running threads */ for (i=0;i<nslcd_cfg->ldc_threads;i++) if (pthread_cancel(nslcd_threads[i])) { } } static void worker_cleanup(void *arg) { MYLDAP_SESSION *session=(MYLDAP_SESSION *)arg; myldap_session_close(session); } static void *worker(void UNUSED(*arg)) { MYLDAP_SESSION *session; /* create a new LDAP session */ session=myldap_create_session(); /* clean up the session if we're done */ pthread_cleanup_push(worker_cleanup,session); /* start waiting for incoming connections */ while (1) { /* wait for a new connection */ acceptconnection(session); } pthread_cleanup_pop(1); return NULL; } int main(int argc,char *argv[]) { ... install_sighandler(SIGTERM,sigexit_handler); install_sighandler(SIGUSR1,sigexit_handler); install_sighandler(SIGUSR2,sigexit_handler); nslcd_threads= (pthread_t *)malloc(nslcd_cfg->ldc_threads*sizeof(pthread_t)); for (i=0;i<nslcd_cfg->ldc_threads;i++) { if (pthread_create(&nslcd_threads[i],NULL,worker,NULL)) { ... exit(EXIT_FAILURE); } } for (i=0;i<nslcd_cfg->ldc_threads;i++) { if (pthread_join(nslcd_threads[i],NULL)) { ... exit(EXIT_FAILURE); } } }
14.
15.
16.
17.
18.
19.
20.
21. static void PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode) { /* Lock the queue mutex */ pthread_mutex_lock (&pQueue->pmMutex); pNode->pNext = NULL; if (pQueue->pTail != NULL) { pQueue->pTail->pNext = pNode; } pQueue->pTail = pNode; if (pQueue->pHead == NULL) { pQueue->pHead = pNode; } /* Increase the count of elements in the queue by one */ ++g_nQueueSize; /* Release the queue mutex */ pthread_mutex_unlock (&pQueue->pmMutex); /* Signal that the queue is not empty */ pthread_cond_signal (&pQueue->pcNotEmpty); } static WMMsgNodePtr PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo) { /* Lock the queue mutex */ pthread_mutex_lock (&pQueue->pmMutex); /* Wait for --- */ while (pQueue->pHead == NULL) { pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex); } pNode = pQueue->pHead; if (pQueue->pHead != NULL) { pQueue->pHead = pQueue->pHead->pNext; } if (pQueue->pTail == pNode) { pQueue->pTail = NULL; } /* Drop the number of elements in the queue by one */ --g_nQueueSize; /* Release the queue mutex */ pthread_mutex_unlock (&pQueue->pmMutex); return pNode; }